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

            Line data    Source code
       1              : #include "precizer.h"
       2              : 
       3              : /**
       4              :  * @brief Validates the integrity of SQLite database file
       5              :  * @details Performs integrity check on the specified database file using either
       6              :  *          quick or full check based on configuration. Also verifies database
       7              :  *          version and upgrades if necessary.
       8              :  *
       9              :  * @param[in] db_file_path Path to the SQLite database file to validate
      10              :  * @return Return status code:
      11              :  *         - SUCCESS: Database validation passed successfully
      12              :  *         - FAILURE: Database validation failed or errors occurred
      13              :  */
      14          152 : Return db_test(const char *db_file_path)
      15              : {
      16              :         /// The status that will be passed to return() before exiting.
      17              :         /// By default, the function worked without errors.
      18          152 :         Return status = SUCCESS;
      19              : 
      20          152 :         sqlite3_stmt *select_stmt = NULL;
      21          152 :         sqlite3 *db = NULL;
      22              : 
      23              :         // Default value
      24          152 :         bool database_is_ok = false;
      25              : 
      26          152 :         const char *db_file_name = NULL;
      27              : 
      28              :         /* Extract file name from path */
      29          152 :         char *dirc = strdup(db_file_path);
      30              : 
      31          152 :         if(dirc == NULL)
      32              :         {
      33            0 :                 serp("Memory allocation failed during strdup operation");
      34            0 :                 provide(FAILURE);
      35              :         }
      36              : 
      37          152 :         db_file_name = basename(dirc);
      38              : 
      39          152 :         if(db_file_name == NULL)
      40              :         {
      41            0 :                 report("basename() failed for path: %s",db_file_path);
      42            0 :                 free(dirc);
      43            0 :                 provide(FAILURE);
      44              :         }
      45              : 
      46              :         /* Check if verification should be skipped */
      47          152 :         if(config->dry_run == true && config->db_primary_file_exists == false)
      48              :         {
      49            0 :                 slog(TRACE,"Dry Run mode is enabled. Database verification for %s is skipped\n",db_file_name);
      50            0 :                 free(dirc);
      51            0 :                 provide(SUCCESS);
      52              :         }
      53              : 
      54              :         /* Open database in read-only mode */
      55          152 :         slog(EVERY,"Starting database file %s integrity check…\n",db_file_name);
      56          152 :         int sqlite_open_flag = SQLITE_OPEN_READONLY;
      57              : 
      58              :         /* Open database */
      59          152 :         int rc = sqlite3_open_v2(db_file_path,&db,sqlite_open_flag,NULL);
      60              : 
      61          152 :         if(rc != SQLITE_OK)
      62              :         {
      63            4 :                 log_sqlite_error(db,rc,NULL,"Can't open database");
      64            4 :                 status = FAILURE;
      65              :         }
      66              : 
      67              :         /* Prepare integrity check statement */
      68          152 :         if(SUCCESS == status)
      69              :         {
      70          148 :                 const char *sql = "PRAGMA integrity_check";
      71              : 
      72          148 :                 if(config->db_check_level == QUICK)
      73              :                 {
      74            2 :                         sql = "PRAGMA quick_check";
      75            2 :                         slog(TRACE,"The database verification level has been set to QUICK\n");
      76              :                 } else {
      77          146 :                         slog(TRACE,"The database verification level has been set to FULL\n");
      78              :                 }
      79              : 
      80          148 :                 rc = sqlite3_prepare_v2(db,sql,-1,&select_stmt,NULL);
      81              : 
      82          148 :                 if(SQLITE_OK != rc)
      83              :                 {
      84            0 :                         log_sqlite_error(db,rc,NULL,"Can't prepare select statement");
      85            0 :                         status = FAILURE;
      86              :                 }
      87              :         }
      88              : 
      89              :         /* Execute integrity check */
      90          152 :         if(SUCCESS == status)
      91              :         {
      92          296 :                 while(SQLITE_ROW == (rc = sqlite3_step(select_stmt)))
      93              :                 {
      94          148 :                         const char *response = (const char *)sqlite3_column_text(select_stmt,0);
      95              : 
      96          148 :                         if(strcmp(response,"ok") == 0)
      97              :                         {
      98          148 :                                 database_is_ok = true;
      99              :                         }
     100              :                 }
     101              : 
     102          148 :                 if(SQLITE_DONE != rc)
     103              :                 {
     104            0 :                         log_sqlite_error(db,rc,NULL,"Select statement didn't finish with DONE");
     105            0 :                         status = FAILURE;
     106              :                 }
     107              :         }
     108              : 
     109          152 :         if(select_stmt != NULL)
     110              :         {
     111          148 :                 sqlite3_finalize(select_stmt);
     112              :         }
     113              : 
     114              :         /* Report integrity check results */
     115          152 :         if(SUCCESS == status)
     116              :         {
     117          148 :                 if(database_is_ok == true)
     118              :                 {
     119          148 :                         slog(EVERY,"Database %s has been verified and is in good condition\n",db_file_name);
     120              :                 } else {
     121            0 :                         slog(ERROR,"The database %s is in poor condition!\n",db_file_name);
     122            0 :                         status = FAILURE;
     123              :                 }
     124              :         }
     125              : 
     126              :         /* Cleanup resources */
     127              : 
     128          152 :         rc = sqlite3_close(db);
     129              : 
     130          152 :         if(SQLITE_OK != rc)
     131              :         {
     132            0 :                 log_sqlite_error(db,rc,NULL,"Warning: failed to close database");
     133            0 :                 status = FAILURE;
     134              :         }
     135              : 
     136              :         /* Check database version if integrity check passed */
     137          152 :         if(SUCCESS == status)
     138              :         {
     139              :                 /* Check the database version number and upgrade the database if necessary */
     140          148 :                 status = db_check_version(db_file_path,db_file_name);
     141              :         }
     142              : 
     143          152 :         if(dirc != NULL)
     144              :         {
     145          152 :                 free(dirc);
     146              :         }
     147              : 
     148          152 :         provide(status);
     149              : }
        

Generated by: LCOV version 2.0-1