DELETE /api/project?name=X — deletes the .db file */
| 1163 | |
| 1164 | /* DELETE /api/project?name=X — deletes the .db file */ |
| 1165 | static void handle_delete_project(cbm_http_server_t *srv, cbm_http_conn_t *c, |
| 1166 | const cbm_http_req_t *req) { |
| 1167 | char name[256] = {0}; |
| 1168 | if (!cbm_http_query_param(req->query, "name", name, (int)sizeof(name)) || name[0] == '\0') { |
| 1169 | cbm_http_replyf(c, 400, g_cors_json, "{\"error\":\"missing name\"}"); |
| 1170 | return; |
| 1171 | } |
| 1172 | |
| 1173 | char db_path[1024]; |
| 1174 | db_path_for_project(name, db_path, sizeof(db_path)); |
| 1175 | if (db_path[0] == '\0') { |
| 1176 | cbm_http_replyf(c, 404, g_cors_json, "{\"error\":\"project not found\"}"); |
| 1177 | return; |
| 1178 | } |
| 1179 | |
| 1180 | if (srv->mutation_begin && !srv->mutation_begin(srv->mutation_context, name)) { |
| 1181 | cbm_http_replyf(c, 423, g_cors_json, |
| 1182 | "{\"error\":\"project is busy; retry after indexing\"}"); |
| 1183 | return; |
| 1184 | } |
| 1185 | bool mutation_held = srv->mutation_begin != NULL; |
| 1186 | |
| 1187 | if (unlink(db_path) != 0) { |
| 1188 | if (errno == ENOENT) { |
| 1189 | unwatch_project(srv, name); |
| 1190 | if (mutation_held) { |
| 1191 | srv->mutation_end(srv->mutation_context, name); |
| 1192 | } |
| 1193 | cbm_http_replyf(c, 404, g_cors_json, "{\"error\":\"project not found\"}"); |
| 1194 | return; |
| 1195 | } |
| 1196 | if (mutation_held) { |
| 1197 | srv->mutation_end(srv->mutation_context, name); |
| 1198 | } |
| 1199 | cbm_http_replyf(c, 500, g_cors_json, "{\"error\":\"failed to delete\"}"); |
| 1200 | return; |
| 1201 | } |
| 1202 | |
| 1203 | /* Also remove WAL and SHM files if they exist */ |
| 1204 | char wal_path[1040], shm_path[1040]; |
| 1205 | snprintf(wal_path, sizeof(wal_path), "%s-wal", db_path); |
| 1206 | snprintf(shm_path, sizeof(shm_path), "%s-shm", db_path); |
| 1207 | (void)unlink(wal_path); |
| 1208 | (void)unlink(shm_path); |
| 1209 | |
| 1210 | unwatch_project(srv, name); |
| 1211 | cbm_log_info("ui.project.deleted", "name", name); |
| 1212 | if (mutation_held) { |
| 1213 | srv->mutation_end(srv->mutation_context, name); |
| 1214 | } |
| 1215 | cbm_http_replyf(c, 200, g_cors_json, "{\"deleted\":true}"); |
| 1216 | } |
| 1217 | |
| 1218 | /* GET /api/project-health?name=X — checks db integrity */ |
| 1219 | static void handle_project_health(cbm_http_conn_t *c, const cbm_http_req_t *req) { |
no test coverage detected