Mercurial > sci
comparison scid/page-api-projects.c @ 18:600204c31bf0
misc: refactor
author | David Demelier <markand@malikania.fr> |
---|---|
date | Tue, 12 Jul 2022 20:20:51 +0200 |
parents | page-api-projects.c@3051ef92173a |
children | f98ea578b1ef |
comparison
equal
deleted
inserted
replaced
17:40fe70256fb0 | 18:600204c31bf0 |
---|---|
1 /* | |
2 * page-api-projects.c -- /api/v?/projects route | |
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 | |
19 #include <assert.h> | |
20 | |
21 #include "config.h" | |
22 #include "db.h" | |
23 #include "log.h" | |
24 #include "page-api-projects.h" | |
25 #include "page.h" | |
26 #include "types.h" | |
27 #include "util.h" | |
28 | |
29 static void | |
30 list(struct kreq *r, const struct project *projects, size_t projectsz) | |
31 { | |
32 struct json_t *doc; | |
33 char *dump; | |
34 | |
35 doc = project_to(projects, projectsz); | |
36 dump = json_dumps(doc, JSON_COMPACT); | |
37 | |
38 khttp_puts(r, dump); | |
39 free(dump); | |
40 json_decref(doc); | |
41 } | |
42 | |
43 static int | |
44 save(const char *json) | |
45 { | |
46 struct project res = {0}; | |
47 int ret = -1; | |
48 | |
49 json_t *doc; | |
50 json_error_t err; | |
51 | |
52 if (!(doc = json_loads(json, 0, &err))) | |
53 log_warn("api/post: invalid JSON input: %s", err.text); | |
54 else if (project_from(&res, 1, doc) < 0) | |
55 log_warn("api/post: failed to decode parameters"); | |
56 else if (db_project_add(&res) < 0) | |
57 log_warn("api/post: database save error"); | |
58 else | |
59 ret = 0; | |
60 | |
61 json_decref(doc); | |
62 | |
63 return ret; | |
64 } | |
65 | |
66 static void | |
67 push(struct kreq *r, const struct project *p) | |
68 { | |
69 struct json_t *json; | |
70 char *dump; | |
71 | |
72 json = project_to(p, 1); | |
73 dump = json_dumps(json, JSON_COMPACT); | |
74 | |
75 khttp_head(r, kresps[KRESP_CONTENT_TYPE], "%s", kmimetypes[KMIME_APP_JSON]); | |
76 khttp_head(r, kresps[KRESP_STATUS], "%s", khttps[KHTTP_200]); | |
77 khttp_body(r); | |
78 khttp_puts(r, dump); | |
79 khttp_free(r); | |
80 | |
81 free(dump); | |
82 json_decref(json); | |
83 } | |
84 | |
85 static void | |
86 get_one(struct kreq *r, const char *name) | |
87 { | |
88 struct db_ctx ctx; | |
89 struct project project = { | |
90 .name = name | |
91 }; | |
92 | |
93 if (db_project_find(&ctx, &project) < 0) | |
94 page(r, NULL, KHTTP_500, KMIME_APP_JSON, NULL); | |
95 else { | |
96 push(r, &project); | |
97 db_ctx_finish(&ctx); | |
98 } | |
99 } | |
100 | |
101 static void | |
102 get_one_id(struct kreq *r, int id) | |
103 { | |
104 struct db_ctx ctx; | |
105 struct project project = { | |
106 .id = id | |
107 }; | |
108 | |
109 if (db_project_find_id(&ctx, &project) < 0) | |
110 page(r, NULL, KHTTP_500, KMIME_APP_JSON, NULL); | |
111 else { | |
112 push(r, &project); | |
113 db_ctx_finish(&ctx); | |
114 } | |
115 } | |
116 | |
117 static void | |
118 get_all(struct kreq *r) | |
119 { | |
120 struct db_ctx ctx; | |
121 struct project projects[SCI_PROJECT_MAX]; | |
122 ssize_t projectsz; | |
123 | |
124 if ((projectsz = db_project_list(&ctx, projects, UTIL_SIZE(projects))) < 0) | |
125 page(r, NULL, KHTTP_500, KMIME_APP_JSON, NULL); | |
126 else { | |
127 khttp_head(r, kresps[KRESP_CONTENT_TYPE], "%s", kmimetypes[KMIME_APP_JSON]); | |
128 khttp_head(r, kresps[KRESP_STATUS], "%s", khttps[KHTTP_200]); | |
129 khttp_body(r); | |
130 list(r, projects, projectsz); | |
131 db_ctx_finish(&ctx); | |
132 khttp_free(r); | |
133 } | |
134 } | |
135 | |
136 static void | |
137 get(struct kreq *r) | |
138 { | |
139 char name[128]; | |
140 int id; | |
141 | |
142 if (sscanf(r->path, "v1/projects/%d", &id) == 1) | |
143 get_one_id(r, id); | |
144 else if (sscanf(r->path, "v1/projects/%127s", name) == 1) | |
145 get_one(r, name); | |
146 else | |
147 get_all(r); | |
148 } | |
149 | |
150 static void | |
151 post(struct kreq *r) | |
152 { | |
153 if (r->fieldsz < 1) | |
154 page(r, NULL, KHTTP_400, KMIME_APP_JSON, NULL); | |
155 else if (save(r->fields[0].val) < 0) | |
156 page(r, NULL, KHTTP_500, KMIME_APP_JSON, NULL); | |
157 else { | |
158 khttp_head(r, kresps[KRESP_CONTENT_TYPE], "%s", kmimetypes[KMIME_APP_JSON]); | |
159 khttp_head(r, kresps[KRESP_STATUS], "%s", khttps[KHTTP_200]); | |
160 khttp_body(r); | |
161 khttp_free(r); | |
162 } | |
163 } | |
164 | |
165 void | |
166 page_api_v1_projects(struct kreq *r) | |
167 { | |
168 assert(r); | |
169 | |
170 switch (r->method) { | |
171 case KMETHOD_GET: | |
172 get(r); | |
173 break; | |
174 case KMETHOD_POST: | |
175 post(r); | |
176 break; | |
177 default: | |
178 page(r, NULL, KHTTP_400, KMIME_APP_JSON, NULL); | |
179 break; | |
180 } | |
181 | |
182 } |