DELETE /api/project?name=X — deletes the .db file */
| 1291 | |
| 1292 | /* DELETE /api/project?name=X — deletes the .db file */ |
| 1293 | static void handle_delete_project(cbm_http_server_t *srv, cbm_http_conn_t *c, |
| 1294 | const cbm_http_req_t *req) { |
| 1295 | char name[256] = {0}; |
| 1296 | if (!cbm_http_query_param(req->query, "name", name, (int)sizeof(name)) || name[0] == '\0') { |
| 1297 | cbm_http_replyf(c, 400, g_cors_json, "{\"error\":\"missing name\"}"); |
| 1298 | return; |
| 1299 | } |
| 1300 | |
| 1301 | char db_path[1024]; |
| 1302 | db_path_for_project(name, db_path, sizeof(db_path)); |
| 1303 | if (db_path[0] == '\0') { |
| 1304 | cbm_http_replyf(c, 404, g_cors_json, "{\"error\":\"project not found\"}"); |
| 1305 | return; |
| 1306 | } |
| 1307 | |
| 1308 | if (srv->mutation_begin && !srv->mutation_begin(srv->mutation_context, name)) { |
| 1309 | cbm_http_replyf(c, 423, g_cors_json, |
| 1310 | "{\"error\":\"project is busy; retry after indexing\"}"); |
| 1311 | return; |
| 1312 | } |
| 1313 | bool mutation_held = srv->mutation_begin != NULL; |
| 1314 | |
| 1315 | if (unlink(db_path) != 0) { |
| 1316 | if (errno == ENOENT) { |
| 1317 | unwatch_project(srv, name); |
| 1318 | if (mutation_held) { |
| 1319 | srv->mutation_end(srv->mutation_context, name); |
| 1320 | } |
| 1321 | cbm_http_replyf(c, 404, g_cors_json, "{\"error\":\"project not found\"}"); |
| 1322 | return; |
| 1323 | } |
| 1324 | if (mutation_held) { |
| 1325 | srv->mutation_end(srv->mutation_context, name); |
| 1326 | } |
| 1327 | cbm_http_replyf(c, 500, g_cors_json, "{\"error\":\"failed to delete\"}"); |
| 1328 | return; |
| 1329 | } |
| 1330 | |
| 1331 | /* Also remove WAL and SHM files if they exist */ |
| 1332 | char wal_path[1040], shm_path[1040]; |
| 1333 | snprintf(wal_path, sizeof(wal_path), "%s-wal", db_path); |
| 1334 | snprintf(shm_path, sizeof(shm_path), "%s-shm", db_path); |
| 1335 | (void)unlink(wal_path); |
| 1336 | (void)unlink(shm_path); |
| 1337 | |
| 1338 | unwatch_project(srv, name); |
| 1339 | cbm_log_info("ui.project.deleted", "name", name); |
| 1340 | if (mutation_held) { |
| 1341 | srv->mutation_end(srv->mutation_context, name); |
| 1342 | } |
| 1343 | cbm_http_replyf(c, 200, g_cors_json, "{\"deleted\":true}"); |
| 1344 | } |
| 1345 | |
| 1346 | /* GET /api/project-health?name=X — checks db integrity */ |
| 1347 | static void handle_project_health(cbm_http_conn_t *c, const cbm_http_req_t *req) { |
no test coverage detected