Route an existing generation. Full rebuilds never delete the live DB here: * publication owns the eventual atomic replacement after every pass and * metadata write has succeeded. */
| 1372 | * publication owns the eventual atomic replacement after every pass and |
| 1373 | * metadata write has succeeded. */ |
| 1374 | static int try_incremental_or_delete_db(cbm_pipeline_t *p, cbm_file_info_t *files, int file_count, |
| 1375 | const cbm_file_hash_t *baseline_manifest, |
| 1376 | int baseline_count, bool force_full_on_mismatch) { |
| 1377 | char *db_path = resolve_db_path(p); |
| 1378 | if (!db_path) { |
| 1379 | return CBM_PIPELINE_FORCE_FULL_REINDEX; |
| 1380 | } |
| 1381 | struct stat db_st; |
| 1382 | if (stat(db_path, &db_st) != 0) { |
| 1383 | free(db_path); |
| 1384 | return CBM_PIPELINE_FORCE_FULL_REINDEX; |
| 1385 | } |
| 1386 | cbm_store_t *check_store = cbm_store_open_path_query(db_path); |
| 1387 | bool valid = check_store && cbm_store_check_integrity(check_store); |
| 1388 | if (check_store) { |
| 1389 | cbm_store_close(check_store); |
| 1390 | } |
| 1391 | if (!valid) { |
| 1392 | cbm_log_warn("pipeline.route", "path", "full", "reason", "invalid_existing_db"); |
| 1393 | free(db_path); |
| 1394 | return CBM_PIPELINE_FORCE_FULL_REINDEX; |
| 1395 | } |
| 1396 | cbm_log_info("pipeline.route", "path", "incremental_manifest"); |
| 1397 | int rc = cbm_pipeline_run_incremental(p, db_path, files, file_count, baseline_manifest, |
| 1398 | baseline_count, force_full_on_mismatch); |
| 1399 | /* Delete the existing generation ONLY when we are about to rebuild it. |
| 1400 | * On main this was guarded by an early `return rc` for the incremental |
| 1401 | * path; this function has no such early return, so the delete must be |
| 1402 | * conditional. Unconditionally removing it destroys the database on the |
| 1403 | * no-op and successful-incremental routes -- the pipeline reports success |
| 1404 | * while every later reader finds no store. */ |
| 1405 | if (rc == CBM_PIPELINE_FORCE_FULL_REINDEX) { |
| 1406 | int adr_rc = capture_existing_adr(p, db_path); |
| 1407 | if (adr_rc != 0) { |
| 1408 | rc = adr_rc; |
| 1409 | } |
| 1410 | (void)cbm_unlink(db_path); |
| 1411 | (void)cbm_remove_db_sidecars(db_path); |
| 1412 | } |
| 1413 | free(db_path); |
| 1414 | return rc; |
| 1415 | } |
| 1416 | |
| 1417 | static const char *pipeline_mode_name(cbm_index_mode_t mode) { |
| 1418 | switch (mode) { |
no test coverage detected