LCOV - code coverage report
Current view: top level - src - db_validate_paths.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 74.0 % 96 71
Test Date: 2026-03-31 13:51:38 Functions: 100.0 % 1 1
Branches: 60.0 % 70 42

             Branch data     Line data    Source code
       1                 :             : #include "precizer.h"
       2                 :             : 
       3                 :             : /**
       4                 :             :  * @brief Validate stored DB path prefixes against current CLI PATH arguments
       5                 :             :  *
       6                 :             :  * @details Skips validation in compare mode. When the primary database has just
       7                 :             :  * been created, no stored-path comparison is needed. Otherwise the function
       8                 :             :  * finds DB prefixes that are missing from the current PATH arguments, stores
       9                 :             :  * their IDs in `the_path_id_does_not_exists`, and reports the mismatch to the
      10                 :             :  * user
      11                 :             :  *
      12                 :             :  * If mismatches are found and `--force` is not enabled, the function returns
      13                 :             :  * `WARNING` so the caller can stop before replacing stored path metadata. When
      14                 :             :  * `--force` is enabled, execution continues and the new PATH arguments may be
      15                 :             :  * written to the database
      16                 :             :  *
      17                 :             :  * @warning Using `--force` incorrectly can replace path, file, and checksum
      18                 :             :  * metadata in the database
      19                 :             :  *
      20                 :             :  * @return `SUCCESS` when paths match or forced path replacement is allowed,
      21                 :             :  *         `WARNING` when mismatches are found without `--force`, or `FAILURE`
      22                 :             :  *         on SQLite or memory errors
      23                 :             :  */
      24                 :         381 : Return db_validate_paths(void)
      25                 :             : {
      26                 :             :         /* Status returned by this function through provide()
      27                 :             :            Default value assumes successful completion */
      28                 :         381 :         Return status = SUCCESS;
      29                 :             : 
      30                 :             :         // Don't do anything
      31         [ +  + ]:         381 :         if(config->compare == true)
      32                 :             :         {
      33                 :         112 :                 provide(status);
      34                 :             :         }
      35                 :             : 
      36                 :             :         /* Interrupt the function smoothly */
      37                 :             :         /* Interrupt when Ctrl+C */
      38         [ -  + ]:         269 :         if(global_interrupt_flag == true)
      39                 :             :         {
      40                 :           0 :                 provide(status);
      41                 :             :         }
      42                 :             : 
      43                 :         269 :         sqlite3_stmt *select_stmt = NULL;
      44                 :         269 :         sqlite3_stmt *insert_stmt = NULL;
      45                 :         269 :         int rc = 0;
      46                 :             : 
      47                 :         269 :         bool paths_are_equal = true;
      48                 :             : 
      49                 :         269 :         create(char,select_sql);
      50                 :             : 
      51                 :             :         // Create the SQL request
      52         [ +  - ]:         269 :         if(config->paths[0] != NULL)
      53                 :             :         {
      54                 :         269 :                 char const *sql_1 = "SELECT ID FROM paths WHERE prefix NOT IN (";
      55                 :             : 
      56                 :         269 :                 status = concat_literal(select_sql,sql_1);
      57                 :             : 
      58         [ -  + ]:         269 :                 if(SUCCESS != status)
      59                 :             :                 {
      60                 :           0 :                         del(select_sql);
      61                 :           0 :                         provide(status);
      62                 :             :                 }
      63                 :             : 
      64         [ +  + ]:         538 :                 for(int i = 0; config->paths[i]; i++)
      65                 :             :                 {
      66                 :         269 :                         create(char,path);
      67                 :             : 
      68   [ +  -  -  + ]:         269 :                         run(db_sql_wrap_string(path,config->paths[i]));
      69                 :             : 
      70   [ +  -  -  + ]:         269 :                         run(concat_literal(select_sql,getcstring(path)));
      71                 :             : 
      72                 :         269 :                         del(path);
      73                 :             : 
      74         [ -  + ]:         269 :                         if(SUCCESS != status)
      75                 :             :                         {
      76                 :           0 :                                 del(select_sql);
      77                 :           0 :                                 provide(status);
      78                 :             :                         }
      79                 :             : 
      80                 :             :                         // Not the last path in the array
      81         [ -  + ]:         269 :                         if(config->paths[i + 1] != 0)
      82                 :             :                         {
      83                 :             :                                 /* Concatenate with the comma character "," */
      84                 :           0 :                                 status = concat_literal(select_sql,",");
      85                 :             : 
      86         [ #  # ]:           0 :                                 if(SUCCESS != status)
      87                 :             :                                 {
      88                 :           0 :                                         del(select_sql);
      89                 :           0 :                                         provide(status);
      90                 :             :                                 }
      91                 :             :                         }
      92                 :             :                 }
      93                 :             : 
      94                 :             :                 /* Close the string that contains SQL request */
      95                 :             : 
      96                 :             :                 /* Concatenate with the ");" characters */
      97                 :         269 :                 status = concat_literal(select_sql,");");
      98                 :             : 
      99         [ -  + ]:         269 :                 if(SUCCESS != status)
     100                 :             :                 {
     101                 :           0 :                         del(select_sql);
     102                 :           0 :                         provide(status);
     103                 :             :                 }
     104                 :             :         }
     105                 :             : 
     106                 :         269 :         rc = sqlite3_prepare_v2(config->db,getcstring(select_sql),-1,&select_stmt,NULL);
     107                 :             : 
     108         [ -  + ]:         269 :         if(SQLITE_OK != rc)
     109                 :             :         {
     110                 :           0 :                 log_sqlite_error(config->db,rc,NULL,"Can't prepare select statement %s",getcstring(select_sql));
     111                 :           0 :                 status = FAILURE;
     112                 :             :         }
     113                 :             : 
     114         [ +  - ]:         269 :         if(SUCCESS == status)
     115                 :             :         {
     116         [ +  + ]:         542 :                 while(SQLITE_ROW == (rc = sqlite3_step(select_stmt)))
     117                 :             :                 {
     118                 :           4 :                         sqlite3_int64 path_ID = -1;
     119                 :             : 
     120                 :           4 :                         path_ID = sqlite3_column_int64(select_stmt,0);
     121                 :             : 
     122         [ -  + ]:           4 :                         if(path_ID != -1)
     123                 :             :                         {
     124                 :           4 :                                 paths_are_equal = false;
     125                 :             : 
     126                 :           4 :                                 const char *insert_sql = "INSERT INTO the_path_id_does_not_exists (path_id) VALUES (?1);";
     127                 :             : 
     128                 :           4 :                                 rc = sqlite3_prepare_v2(config->db,insert_sql,-1,&insert_stmt,NULL);
     129                 :             : 
     130         [ -  + ]:           4 :                                 if(SQLITE_OK != rc)
     131                 :             :                                 {
     132                 :           0 :                                         log_sqlite_error(config->db,rc,NULL,"Can't prepare insert statement");
     133                 :           0 :                                         status = FAILURE;
     134                 :             :                                 }
     135                 :             : 
     136         [ +  - ]:           4 :                                 if(SUCCESS == status)
     137                 :             :                                 {
     138                 :           4 :                                         rc = sqlite3_bind_int64(insert_stmt,1,path_ID);
     139                 :             : 
     140         [ -  + ]:           4 :                                         if(SQLITE_OK != rc)
     141                 :             :                                         {
     142                 :           0 :                                                 log_sqlite_error(config->db,rc,NULL,"Error binding value in insert");
     143                 :           0 :                                                 status = FAILURE;
     144                 :             :                                         }
     145                 :             :                                 }
     146                 :             : 
     147         [ +  - ]:           4 :                                 if(SUCCESS == status)
     148                 :             :                                 {
     149                 :             :                                         /* Execute SQL statement */
     150                 :           4 :                                         rc = sqlite3_step(insert_stmt);
     151                 :             : 
     152         [ -  + ]:           4 :                                         if(rc != SQLITE_DONE)
     153                 :             :                                         {
     154                 :           0 :                                                 log_sqlite_error(config->db,rc,NULL,"Insert statement didn't return DONE");
     155                 :           0 :                                                 status = FAILURE;
     156                 :             :                                         }
     157                 :             :                                 }
     158                 :             : 
     159                 :           4 :                                 sqlite3_finalize(insert_stmt);
     160                 :             :                         }
     161                 :             :                 }
     162                 :             : 
     163         [ -  + ]:         269 :                 if(SQLITE_DONE != rc)
     164                 :             :                 {
     165                 :           0 :                         log_sqlite_error(config->db,rc,NULL,"Select statement didn't finish with DONE");
     166                 :           0 :                         status = FAILURE;
     167                 :             :                 }
     168                 :             :         }
     169                 :             : 
     170                 :         269 :         del(select_sql);
     171                 :             : 
     172                 :         269 :         sqlite3_finalize(select_stmt);
     173                 :             : 
     174         [ +  - ]:         269 :         if(SUCCESS == status)
     175                 :             :         {
     176                 :             :                 /* If the primary database was just created */
     177   [ +  +  +  - ]:         269 :                 if(config->db_primary_file_exists == false && config->compare == false)
     178                 :             :                 {
     179                 :         159 :                         slog(TRACE,"The brand new database has just been created. No need to verify the paths stored in the database against those passed as command-line arguments\n");
     180                 :         159 :                         provide(status);
     181                 :             : 
     182                 :             :                 } else {
     183                 :             : 
     184         [ +  + ]:         110 :                         if(paths_are_equal == true)
     185                 :             :                         {
     186                 :         106 :                                 slog(TRACE,"The paths written against the database and the paths passed as arguments are completely identical\n");
     187                 :             :                         } else {
     188                 :           4 :                                 slog(EVERY,"The paths passed as arguments differ from those saved in the database. File paths and checksum information may be lost!\n");
     189                 :             : 
     190         [ +  - ]:           4 :                                 if(!(rational_logger_mode & SILENT))
     191                 :             :                                 {
     192                 :           4 :                                         slog(EVERY,"Paths saved in the database:\n");
     193                 :             : 
     194                 :             :                                         sqlite3_stmt *stmt;
     195                 :           4 :                                         int rc_stmt = 0;
     196                 :           4 :                                         char const *sql = "SELECT prefix FROM paths;";
     197                 :             : 
     198                 :           4 :                                         rc_stmt = sqlite3_prepare_v2(config->db,sql,-1,&stmt,NULL);
     199                 :             : 
     200         [ -  + ]:           4 :                                         if(SQLITE_OK != rc_stmt)
     201                 :             :                                         {
     202                 :           0 :                                                 log_sqlite_error(config->db,rc_stmt,NULL,"Can't prepare select statement %s",sql);
     203                 :           0 :                                                 status = FAILURE;
     204                 :             :                                         }
     205                 :             : 
     206         [ +  - ]:           4 :                                         if(SUCCESS == status)
     207                 :             :                                         {
     208         [ +  + ]:           8 :                                                 while(SQLITE_ROW == (rc_stmt = sqlite3_step(stmt)))
     209                 :             :                                                 {
     210                 :           4 :                                                         const char *prefix = (const char *)sqlite3_column_text(stmt,0);
     211                 :             : 
     212                 :           4 :                                                         slog(EVERY|UNDECOR,"%s\n",prefix);
     213                 :             :                                                 }
     214                 :             : 
     215         [ -  + ]:           4 :                                                 if(SQLITE_DONE != rc_stmt)
     216                 :             :                                                 {
     217                 :           0 :                                                         log_sqlite_error(config->db,rc_stmt,NULL,"Select statement didn't finish with DONE");
     218                 :           0 :                                                         status = FAILURE;
     219                 :             :                                                 }
     220                 :             :                                         }
     221                 :             : 
     222                 :           4 :                                         sqlite3_finalize(stmt);
     223                 :             :                                 }
     224                 :             : 
     225         [ +  + ]:           4 :                                 if(config->force == true)
     226                 :             :                                 {
     227         [ +  - ]:           2 :                                         if(!(rational_logger_mode & SILENT))
     228                 :             :                                         {
     229                 :           2 :                                                 slog(EVERY,"The " BOLD "--force" RESET " option has been used, so the following paths will be written to the %s:\n",confstr(db_file_name));
     230                 :             : 
     231         [ +  + ]:           4 :                                                 for(int i = 0; config->paths[i]; i++)
     232                 :             :                                                 {
     233                 :           2 :                                                         slog(EVERY|UNDECOR,"%s\n",config->paths[i]);
     234                 :             :                                                 }
     235                 :             :                                         }
     236                 :             :                                 } else {
     237                 :           2 :                                         slog(EVERY,"Use the " BOLD "--force" RESET " option only when the PATHS stored in the database need"
     238                 :             :                                                 " to be updated. Warning: If this option is used incorrectly, file and checksum information"
     239                 :             :                                                 " in the database may be lost or completely replaced with different values.\n");
     240                 :           2 :                                         status = WARNING;
     241                 :             :                                 }
     242                 :             :                         }
     243                 :             :                 }
     244                 :             :         }
     245                 :             : 
     246                 :         110 :         provide(status);
     247                 :             : }
        

Generated by: LCOV version 2.0-1