Branch data 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 : 283 : Return db_delete_missing_metadata(void)
10 : : {
11 : : /* Status returned by this function through provide()
12 : : Default value assumes successful completion */
13 : 283 : Return status = SUCCESS;
14 : :
15 : : /* Interrupt the function smoothly */
16 : : /* Interrupt when Ctrl+C */
17 [ - + ]: 283 : if(global_interrupt_flag == true)
18 : : {
19 : 0 : provide(status);
20 : : }
21 : :
22 : : /* Skip in comparison mode */
23 [ + + ]: 283 : if(config->compare == true)
24 : : {
25 : 70 : slog(TRACE,"Comparison mode is enabled. The primary database does not require cleanup\n");
26 : 70 : provide(status);
27 : : }
28 : :
29 : : /* Update mode should be enabled */
30 [ + + ]: 213 : if(config->update == true)
31 : : {
32 : 92 : slog(EVERY,"Searching for files that no longer exist on the file system…\n");
33 : :
34 : : } else {
35 : : // Don't do anything
36 : 121 : provide(status);
37 : : }
38 : :
39 [ + + + - ]: 92 : if(config->dry_run == true && config->db_primary_file_exists == true)
40 : : {
41 : 10 : 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 : 92 : bool first_iteration = true;
46 : :
47 : 92 : sqlite3_stmt *select_stmt = NULL;
48 : :
49 : 92 : 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 : 92 : const char *select_sql = "SELECT files.ID,paths.prefix,files.relative_path FROM files,paths;";
55 : :
56 : 92 : rc = sqlite3_prepare_v2(config->db,select_sql,-1,&select_stmt,NULL);
57 : :
58 [ - + ]: 92 : 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 [ + + ]: 1260 : while(SQLITE_ROW == (rc = sqlite3_step(select_stmt)))
65 : : {
66 : : /* Interrupt the loop smoothly */
67 : : /* Interrupt when Ctrl+C */
68 [ - + ]: 1168 : if(global_interrupt_flag == true)
69 : : {
70 : 0 : break;
71 : : }
72 : :
73 : 1168 : sqlite_int64 ID = sqlite3_column_int64(select_stmt,0);
74 : 1168 : const char *runtime_path_prefix = (const char *)sqlite3_column_text(select_stmt,1);
75 : 1168 : const char *relative_path = (const char *)sqlite3_column_text(select_stmt,2);
76 : :
77 : : // Marks deletions triggered by --db-drop-ignored
78 : 1168 : bool drop_ignored = false;
79 : :
80 [ + - + - ]: 1168 : 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 [ + + ]: 1168 : if(config->db_drop_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 : 188 : Ignore match_ignore_response = match_ignore_pattern(relative_path,&showed_once);
110 : :
111 [ + + ]: 188 : if(IGNORE == match_ignore_response)
112 : : {
113 : 46 : drop_ignored = true;
114 : :
115 [ - + ]: 142 : } else if(FAIL_REGEXP_IGNORE == match_ignore_response){
116 : 0 : status = FAILURE;
117 : : }
118 : :
119 [ - + ]: 8 : } 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 [ + + + - ]: 1168 : if(drop_ignored == true || relative_path != NULL)
128 : : {
129 : 1168 : status = db_delete_the_record_by_id(&ID,
130 : : &first_iteration,
131 : : &drop_ignored,
132 : : relative_path,
133 : : runtime_path_prefix);
134 : :
135 [ - + ]: 1168 : if(SUCCESS != status)
136 : : {
137 : 0 : break;
138 : : }
139 : : }
140 : : }
141 : :
142 [ - + ]: 92 : 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 : 92 : sqlite3_finalize(select_stmt);
152 : :
153 : 92 : slog(EVERY,"Missing file search completed\n");
154 : :
155 : 92 : provide(status);
156 : : }
|