LCOV - code coverage report
Current view: top level - src - db_delete_the_record_by_id.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 84.6 % 65 55
Test Date: 2026-03-01 04:31:48 Functions: 100.0 % 1 1
Branches: 76.0 % 50 38

             Branch data     Line data    Source code
       1                 :             : #include "precizer.h"
       2                 :             : 
       3                 :             : /**
       4                 :             :  *
       5                 :             :  * Drop a file record from the database by its unique ID.
       6                 :             :  * Records are dropped only for ignored paths, missing files, or inaccessible
       7                 :             :  * paths when --db-drop-inaccessible is enabled; accessible paths remain.
       8                 :             :  * In --dry-run mode, the database is not modified.
       9                 :             :  *
      10                 :             :  */
      11                 :        1168 : Return db_delete_the_record_by_id(
      12                 :             :         const sqlite_int64 *ID,
      13                 :             :         bool               *first_iteration,
      14                 :             :         const bool         *drop_ignored,
      15                 :             :         const char         *relative_path,
      16                 :             :         const char         *runtime_path_prefix)
      17                 :             : {
      18                 :             :         /* Status returned by this function through provide()
      19                 :             :            Default value assumes successful completion */
      20                 :        1168 :         Return status = SUCCESS;
      21                 :             : 
      22                 :             :         // Indicates removal due to missing or unreadable path
      23                 :        1168 :         bool inaccessible = false;
      24                 :             : 
      25                 :        1168 :         bool file_not_found = false;
      26                 :             : 
      27                 :        1168 :         char *absolute_path = NULL;
      28                 :             : 
      29   [ +  -  +  + ]:        1168 :         if(drop_ignored != NULL && *drop_ignored == false
      30   [ +  -  +  - ]:        1122 :                 && runtime_path_prefix != NULL && relative_path != NULL)
      31                 :             :         {
      32                 :        1122 :                 int length = asprintf(&absolute_path,"%s/%s",runtime_path_prefix,relative_path);
      33                 :             : 
      34         [ -  + ]:        1122 :                 if(length == -1)
      35                 :             :                 {
      36                 :           0 :                         free(absolute_path);
      37                 :           0 :                         return(FAILURE);
      38                 :             :                 }
      39                 :             : 
      40                 :        1122 :                 FileAccessStatus access_status = file_check_access(absolute_path,(size_t)length,R_OK);
      41                 :             : 
      42                 :        1122 :                 free(absolute_path);
      43                 :             : 
      44         [ -  + ]:        1122 :                 if(access_status == FILE_ACCESS_ERROR)
      45                 :             :                 {
      46                 :           0 :                         return(FAILURE);
      47                 :             :                 }
      48                 :             : 
      49         [ +  + ]:        1122 :                 if(access_status == FILE_NOT_FOUND)
      50                 :             :                 {
      51                 :          26 :                         file_not_found = true;
      52                 :             : 
      53         [ +  + ]:        1096 :                 } else if(access_status == FILE_ACCESS_DENIED){
      54                 :             : 
      55         [ +  + ]:           8 :                         if(config->db_drop_inaccessible == true)
      56                 :             :                         {
      57                 :           4 :                                 inaccessible = true;
      58                 :             : 
      59                 :             :                         } else {
      60                 :             : 
      61                 :           4 :                                 slog(EVERY|UNDECOR,"kept inaccessible %s\n",relative_path);
      62                 :             : 
      63                 :           4 :                                 return(SUCCESS);
      64                 :             : 
      65                 :             :                         }
      66                 :             : 
      67         [ +  - ]:        1088 :                 } else if(access_status == FILE_ACCESS_ALLOWED){
      68                 :             : 
      69                 :             :                         /* The file remains available.
      70                 :             :                            Keep file references in the database! */
      71                 :        1088 :                         return(SUCCESS);
      72                 :             :                 }
      73                 :             :         }
      74                 :             : 
      75                 :          76 :         sqlite3_stmt *delete_stmt = NULL;
      76                 :          76 :         int rc = 0;
      77                 :             : 
      78                 :          76 :         const char *sql = "DELETE FROM files WHERE ID=?1;";
      79                 :             : 
      80                 :             :         // Don't do anything in case of --dry-run
      81         [ +  + ]:          76 :         if(config->dry_run == true)
      82                 :             :         {
      83                 :          14 :                 sql = "SELECT ID FROM files WHERE ID=?1;";
      84                 :             :         }
      85                 :             : 
      86                 :          76 :         rc = sqlite3_prepare_v2(config->db,sql,-1,&delete_stmt,NULL);
      87                 :             : 
      88         [ -  + ]:          76 :         if(SQLITE_OK != rc)
      89                 :             :         {
      90                 :           0 :                 log_sqlite_error(config->db,rc,NULL,"Can't prepare delete statement");
      91                 :           0 :                 status = FAILURE;
      92                 :             :         }
      93                 :             : 
      94         [ +  - ]:          76 :         if(SUCCESS == status)
      95                 :             :         {
      96                 :          76 :                 rc = sqlite3_bind_int64(delete_stmt,1,*ID);
      97                 :             : 
      98         [ -  + ]:          76 :                 if(SQLITE_OK != rc)
      99                 :             :                 {
     100                 :           0 :                         log_sqlite_error(config->db,rc,NULL,"Error binding value in delete");
     101                 :           0 :                         status = FAILURE;
     102                 :             :                 }
     103                 :             :         }
     104                 :             : 
     105         [ +  - ]:          76 :         if(SUCCESS == status)
     106                 :             :         {
     107                 :          76 :                 int sql_return = SQLITE_DONE;
     108                 :             : 
     109                 :             :                 // Select instead Delete in Dry Run mode
     110         [ +  + ]:          76 :                 if(config->dry_run == true)
     111                 :             :                 {
     112                 :          14 :                         sql_return = SQLITE_ROW;
     113                 :             :                 }
     114                 :             : 
     115                 :             :                 /* Execute SQL statement */
     116         [ +  - ]:          76 :                 if(sqlite3_step(delete_stmt) == sql_return)
     117                 :             :                 {
     118         [ +  + ]:          76 :                         if(*first_iteration == true)
     119                 :             :                         {
     120                 :          32 :                                 *first_iteration = false;
     121                 :             : 
     122         [ +  + ]:          32 :                                 if(config->ignore != NULL)
     123                 :             :                                 {
     124         [ +  + ]:          16 :                                         if(config->db_drop_ignored == false)
     125                 :             :                                         {
     126                 :           4 :                                                 slog(EVERY,"If the information about ignored files should be removed from the database the " BOLD "--db-drop-ignored" RESET " option must be specified. This is special protection against accidental deletion of information from the database\n");
     127                 :             :                                         } else {
     128                 :          12 :                                                 slog(TRACE,"The " BOLD "--db-drop-ignored" RESET " option has been used, so the information about ignored files will be removed against the database %s\n",confstr(db_file_name));
     129                 :             :                                         }
     130                 :             :                                 }
     131                 :             : 
     132                 :             :                                 /* Reflect changes in global */
     133         [ +  + ]:          32 :                                 if(config->dry_run == false)
     134                 :             :                                 {
     135                 :          24 :                                         config->db_primary_file_modified = true;
     136                 :             :                                 }
     137                 :             : 
     138         [ +  + ]:          32 :                                 if(config->db_drop_inaccessible)
     139                 :             :                                 {
     140                 :           2 :                                         slog(EVERY,BOLD "Dropping DB records for missing, inaccessible, or ignored paths in %s:" RESET "\n",confstr(db_file_name));
     141                 :             :                                 } else {
     142                 :          30 :                                         slog(EVERY,BOLD "Dropping DB records for missing or ignored paths in %s:" RESET "\n",confstr(db_file_name));
     143                 :             :                                 }
     144                 :             :                         }
     145                 :             : 
     146         [ +  + ]:          76 :                         if(*drop_ignored == true)
     147                 :             :                         {
     148                 :          46 :                                 slog(EVERY|UNDECOR|REMEMBER,"drop ignored %s\n",relative_path);
     149                 :             : 
     150         [ +  + ]:          30 :                         } else if(inaccessible == true){
     151                 :             : 
     152                 :           4 :                                 slog(EVERY|UNDECOR|REMEMBER,"drop due to inaccessible %s\n",relative_path);
     153                 :             : 
     154         [ +  - ]:          26 :                         } else if(file_not_found == true){
     155                 :             : 
     156                 :          26 :                                 slog(EVERY|UNDECOR,"no longer exists %s\n",relative_path);
     157                 :             : 
     158                 :             :                         } else {
     159                 :             : 
     160                 :           0 :                                 slog(ERROR,"An unexpected error that should never occur for %s\n",relative_path);
     161                 :             :                         }
     162                 :             : 
     163                 :             :                 } else {
     164                 :             : 
     165                 :           0 :                         log_sqlite_error(config->db,rc,NULL,"Delete statement didn't return right code %d",sql_return);
     166                 :           0 :                         status = FAILURE;
     167                 :             :                 }
     168                 :             :         }
     169                 :             : 
     170                 :          76 :         sqlite3_finalize(delete_stmt);
     171                 :             : 
     172                 :          76 :         provide(status);
     173                 :             : }
        

Generated by: LCOV version 2.0-1