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 : : }
|