Branch data Line data Source code
1 : : #include "precizer.h"
2 : :
3 : : /**
4 : : * @brief Save the current per-file state into the database
5 : : *
6 : : * This function is the common save point for one file row. It writes the file's
7 : : * current metadata, SHA512 digest or partial SHA512 resume state, and row status
8 : : * to SQLite. It chooses whether to insert a new row or update an existing row by
9 : : * looking at @p path_known
10 : : *
11 : : * The helper is used by both final file saves and silent SHA512 checkpoints. A
12 : : * checkpoint may be the first time a new file is written to SQLite during the
13 : : * current traversal. In that case the helper inserts the row, stores the new row
14 : : * ID in @p file, and updates @p path_known so later saves for the same file
15 : : * update that row instead of inserting a duplicate. When @p path_known is already
16 : : * true, the helper updates the existing row directly
17 : : *
18 : : * Writes join the current main-traversal transaction. Periodic checkpoints and
19 : : * traversal completion commit the pending records, so a successful save alone
20 : : * does not mean the row has been committed
21 : : *
22 : : * @p mark_visible_change controls user-facing reporting. Final saves pass true
23 : : * so show_file() can say whether the file was inserted or updated. Silent
24 : : * checkpoints pass false because they are only recovery points for interrupted
25 : : * hashing and should not appear as ordinary traversal changes
26 : : *
27 : : * @param[in] relative_path File path relative to the traversal root
28 : : * @param[in,out] file Per-file state to persist and annotate
29 : : * @param[in,out] path_known True when the row currently exists in SQLite
30 : : * @param[in] mark_visible_change True for the final save reported to the user
31 : : * @return SUCCESS when the row was saved, otherwise FAILURE
32 : : */
33 : 3608 : Return db_save_file_record(
34 : : const memory *relative_path,
35 : : File *file,
36 : : bool *path_known,
37 : : const bool mark_visible_change)
38 : : {
39 : : /* Status returned by this function through provide()
40 : : Default value assumes successful completion */
41 : 3608 : Return status = SUCCESS;
42 : :
43 [ + - + - : 3608 : if(relative_path == NULL || file == NULL || file->db == NULL || path_known == NULL)
+ - - + ]
44 : : {
45 : 0 : provide(FAILURE);
46 : : }
47 : :
48 [ + + - + ]: 3608 : if(config->dry_run == true && mark_visible_change == false)
49 : : {
50 : 0 : provide(status);
51 : : }
52 : :
53 : : /*
54 : : * Use the active transaction or start one before saving this file.
55 : : * Grouping file writes reduces commit overhead. call() allows the partial
56 : : * SHA512 state to be saved even during graceful interruption
57 : : */
58 : 3608 : call(db_file_transaction_begin());
59 : :
60 [ - + ]: 3608 : if(FAILURE & status)
61 : : {
62 : 0 : provide(status);
63 : : }
64 : :
65 : : /*
66 : : * Remember whether the row existed before this file started processing.
67 : : * A silent checkpoint can insert a new row before the final save, but the
68 : : * user-facing result should still say "inserted", not "updated"
69 : : */
70 : 3608 : const bool row_existed_before_processing = file->db->relative_path_was_in_db_before_processing == true;
71 : :
72 : : /*
73 : : * Save into the row that is known for the current traversal state.
74 : : * Existing paths are updated by ID. New paths are inserted once, then their
75 : : * generated ID and path_known flag are kept so later checkpoints or the final
76 : : * save update the same row instead of inserting another one
77 : : */
78 [ + + ]: 3608 : if(*path_known == true)
79 : : {
80 : 268 : status = db_update_the_record_by_id(file);
81 : :
82 : : } else {
83 : 3340 : status = db_insert_the_record(relative_path,file);
84 : :
85 [ + - ]: 3340 : if(SUCCESS & status)
86 : : {
87 [ + + ]: 3340 : if(config->dry_run == false)
88 : : {
89 : 2652 : file->db->ID = sqlite3_last_insert_rowid(config->db);
90 : 2652 : *path_known = true;
91 : : }
92 : : }
93 : : }
94 : :
95 : : /*
96 : : * Mark only visible saves for the traversal report.
97 : : * Silent checkpoints may write the same row earlier, but they must not make
98 : : * the file look updated to the user. The original row state decides whether
99 : : * the final visible result is an insertion or an update
100 : : */
101 [ + - + + ]: 3608 : if((SUCCESS & status) && mark_visible_change == true)
102 : : {
103 [ + + ]: 3604 : if(row_existed_before_processing == true)
104 : : {
105 : 266 : file->db_record_updated = true;
106 : :
107 : : } else {
108 : 3338 : file->new_db_record_inserted = true;
109 : : }
110 : : }
111 : :
112 : 3608 : provide(status);
113 : : }
|