LCOV - code coverage report
Current view: top level - src - db_delete_missing_metadata.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 78.4 % 51 40
Test Date: 2026-01-12 05:34:38 Functions: 100.0 % 1 1

            Line data    Source code
       1              : #include "precizer.h"
       2              : 
       3              : /**
       4              :  *
       5              :  * Remove information from the database about files that had been deleted
       6              :  * on the file system or have been ignored
       7              :  *
       8              :  */
       9          178 : Return db_delete_missing_metadata(void)
      10              : {
      11              :         /// The status that will be passed to return() before exiting.
      12              :         /// By default, the function worked without errors.
      13          178 :         Return status = SUCCESS;
      14              : 
      15              :         /* Interrupt the function smoothly */
      16              :         /* Interrupt when Ctrl+C */
      17          178 :         if(global_interrupt_flag == true)
      18              :         {
      19            0 :                 provide(status);
      20              :         }
      21              : 
      22              :         /* Skip in comparison mode */
      23          178 :         if(config->compare == true)
      24              :         {
      25           32 :                 slog(TRACE,"Comparison mode is enabled. The primary database does not require cleanup\n");
      26           32 :                 provide(status);
      27              :         }
      28              : 
      29              :         /* Update mode should be enabled */
      30          146 :         if(config->update == true)
      31              :         {
      32           68 :                 slog(EVERY,"Searching for files that no longer exist on the file system…\n");
      33              : 
      34              :         } else {
      35              :                 // Don't do anything
      36           78 :                 provide(status);
      37              :         }
      38              : 
      39           68 :         if(config->dry_run == true && config->db_primary_file_exists == true)
      40              :         {
      41            8 :                 slog(TRACE,"Dry Run mode is enabled. The primary database must not be modified\n");
      42              :         }
      43              : 
      44              :         // Print deletion banners only once per run
      45           68 :         bool first_iteration = true;
      46              : 
      47           68 :         sqlite3_stmt *select_stmt = NULL;
      48              : 
      49           68 :         int rc = 0;
      50              : 
      51              : #if 0 // Old multiPATH solutions
      52              :         const char *select_sql = "SELECT files.ID,paths.prefix,files.relative_path FROM files LEFT JOIN paths ON files.path_prefix_index = paths.ID;";
      53              : #endif
      54           68 :         const char *select_sql = "SELECT files.ID,paths.prefix,files.relative_path FROM files,paths;";
      55              : 
      56           68 :         rc = sqlite3_prepare_v2(config->db,select_sql,-1,&select_stmt,NULL);
      57              : 
      58           68 :         if(SQLITE_OK != rc)
      59              :         {
      60            0 :                 log_sqlite_error(config->db,rc,NULL,"Can't prepare select statement");
      61            0 :                 status = FAILURE;
      62              :         }
      63              : 
      64          958 :         while(SQLITE_ROW == (rc = sqlite3_step(select_stmt)))
      65              :         {
      66              :                 /* Interrupt the loop smoothly */
      67              :                 /* Interrupt when Ctrl+C */
      68          890 :                 if(global_interrupt_flag == true)
      69              :                 {
      70            0 :                         break;
      71              :                 }
      72              : 
      73          890 :                 sqlite_int64 ID = sqlite3_column_int64(select_stmt,0);
      74          890 :                 const char *runtime_path_prefix = (const char *)sqlite3_column_text(select_stmt,1);
      75          890 :                 const char *relative_path = (const char *)sqlite3_column_text(select_stmt,2);
      76              : 
      77              :                 // Marks deletions triggered by --db-clean-ignored
      78          890 :                 bool clean_ignored = false;
      79              : 
      80          890 :                 if(runtime_path_prefix != NULL && relative_path != NULL)
      81              :                 {
      82              :                         /*
      83              :                          * Remove from the database mention of
      84              :                          * files that matches the regular expression
      85              :                          * passed through the ignore option(s)
      86              :                          *
      87              :                          */
      88          890 :                         if(config->db_clean_ignored == true)
      89              :                         {
      90              :                                 /*
      91              :                                  *
      92              :                                  * PCRE2 regexp to include the file
      93              :                                  *
      94              :                                  */
      95              : 
      96              :                                 // Don't show extra messages
      97          196 :                                 bool showed_once = true;
      98              : 
      99          196 :                                 Include match_include_response = match_include_pattern(relative_path,&showed_once);
     100              : 
     101          196 :                                 if(DO_NOT_INCLUDE == match_include_response)
     102              :                                 {
     103              :                                         /*
     104              :                                          *
     105              :                                          * PCRE2 regexp to ignore the file
     106              :                                          *
     107              :                                          */
     108              : 
     109          190 :                                         Ignore match_ignore_response = match_ignore_pattern(relative_path,&showed_once);
     110              : 
     111          190 :                                         if(IGNORE == match_ignore_response)
     112              :                                         {
     113           52 :                                                 clean_ignored = true;
     114              : 
     115          138 :                                         } else if(FAIL_REGEXP_IGNORE == match_ignore_response){
     116            0 :                                                 status = FAILURE;
     117              :                                         }
     118              : 
     119            6 :                                 } else if(FAIL_REGEXP_INCLUDE == match_include_response){
     120            0 :                                         status = FAILURE;
     121            0 :                                         break;
     122              :                                 }
     123              :                         }
     124              :                 }
     125              : 
     126              :                 // Decide on deletion; access check and messaging handled inside db_delete_the_record_by_id
     127          890 :                 if(clean_ignored == true || relative_path != NULL)
     128              :                 {
     129          890 :                         status = db_delete_the_record_by_id(&ID,
     130              :                                 &first_iteration,
     131              :                                 &clean_ignored,
     132              :                                 relative_path,
     133              :                                 runtime_path_prefix);
     134              : 
     135          890 :                         if(SUCCESS != status)
     136              :                         {
     137            0 :                                 break;
     138              :                         }
     139              :                 }
     140              :         }
     141              : 
     142           68 :         if(SQLITE_DONE != rc)
     143              :         {
     144            0 :                 if(global_interrupt_flag == false)
     145              :                 {
     146            0 :                         log_sqlite_error(config->db,rc,NULL,"Select statement didn't finish with DONE");
     147            0 :                         status = FAILURE;
     148              :                 }
     149              :         }
     150              : 
     151           68 :         sqlite3_finalize(select_stmt);
     152              : 
     153           68 :         slog(EVERY,"Missing file search completed\n");
     154              : 
     155           68 :         provide(status);
     156              : }
        

Generated by: LCOV version 2.0-1