Branch data Line data Source code
1 : : /**
2 : : * @file db_insert_the_record.c
3 : : * @brief Insert new file rows into the SQLite database
4 : : * @details Contains the implementation that binds relative path, checksum, offset,
5 : : * and metadata fields for a new files table record
6 : : */
7 : :
8 : : #include "precizer.h"
9 : :
10 : : /**
11 : : * @brief Insert one file record into the database
12 : : *
13 : : * Binds the relative path, checksum offset, SHA512 digest, compact stat payload,
14 : : * and saved hashing context for one files-table row.
15 : : * Some bound fields may be NULL when the current file state does not have data for them
16 : : *
17 : : * @param[in] relative_path Descriptor containing the file path relative to the traversal root
18 : : * @param[in] file Per-file state object used to bind the row payload
19 : : * @return SUCCESS when the record was handled cleanly, otherwise FAILURE
20 : : *
21 : : * @note In dry-run mode, the function returns SUCCESS without modifying the database
22 : : */
23 : 2476 : Return db_insert_the_record(
24 : : const memory *relative_path,
25 : : const File *file)
26 : : {
27 : : /* Status returned by this function through provide()
28 : : Default value assumes successful completion */
29 : 2476 : Return status = SUCCESS;
30 : :
31 : : /* Skip database operations in dry run mode --dry-run */
32 [ + + ]: 2476 : if(config->dry_run == true)
33 : : {
34 : 80 : provide(status);
35 : : }
36 : :
37 : 2396 : int rc = 0;
38 : :
39 : 2396 : sqlite3_stmt *insert_stmt = NULL;
40 : :
41 : : #if 0 // Disabled multi-root path index implementation
42 : : const char *insert_sql = "INSERT INTO files (offset,path_prefix_index,relative_path,sha512,stat,mdContext) VALUES (?1, ?2, ?3, ?4, ?5, ?6);";
43 : : #else
44 : 2396 : const char *insert_sql = "INSERT INTO files (offset,relative_path,sha512,stat,mdContext) VALUES (?1, ?2, ?3, ?4, ?5);";
45 : : #endif
46 : :
47 : : /* Prepare SQL statement */
48 : 2396 : rc = sqlite3_prepare_v2(config->db,insert_sql,-1,&insert_stmt,NULL);
49 : :
50 [ - + ]: 2396 : if(SQLITE_OK != rc)
51 : : {
52 : 0 : log_sqlite_error(config->db,rc,NULL,"Failed to prepare insert statement %s",insert_sql);
53 : 0 : status = FAILURE;
54 : : }
55 : :
56 : : /* Bind offset value */
57 [ + - ]: 2396 : if(SUCCESS & status)
58 : : {
59 [ + + ]: 2396 : if(file->checksum_offset == 0)
60 : : {
61 : 2391 : rc = sqlite3_bind_null(insert_stmt,1);
62 : : } else {
63 : 5 : rc = sqlite3_bind_int64(insert_stmt,1,file->checksum_offset);
64 : : }
65 : :
66 [ - + ]: 2396 : if(SQLITE_OK != rc)
67 : : {
68 : 0 : log_sqlite_error(config->db,rc,NULL,"Failed to bind offset value");
69 : 0 : status = FAILURE;
70 : : }
71 : : }
72 : :
73 : : /* Bind relative path */
74 [ + - ]: 2396 : if(SUCCESS & status)
75 : : {
76 : : size_t relative_path_length;
77 : :
78 : 2396 : status = m_string_length(relative_path,&relative_path_length);
79 : :
80 [ + - ]: 2396 : if(SUCCESS & status)
81 : : {
82 : 2396 : rc = sqlite3_bind_text(insert_stmt,2,m_text(relative_path),(int)relative_path_length,NULL);
83 : :
84 [ - + ]: 2396 : if(SQLITE_OK != rc)
85 : : {
86 : 0 : log_sqlite_error(config->db,rc,NULL,"Failed to bind relative path");
87 : 0 : status = FAILURE;
88 : : }
89 : : }
90 : : }
91 : :
92 : : /* Bind SHA512 checksum */
93 [ + - ]: 2396 : if(SUCCESS & status)
94 : : {
95 [ + + + + : 2396 : if(file->checksum_offset == 0 && file->zero_size_file == false && file->wrong_file_type == false)
+ - ]
96 : : {
97 : 2387 : rc = sqlite3_bind_blob(insert_stmt,3,file->sha512,SHA512_DIGEST_LENGTH,NULL);
98 : : } else {
99 : 9 : rc = sqlite3_bind_null(insert_stmt,3);
100 : : }
101 : :
102 [ - + ]: 2396 : if(SQLITE_OK != rc)
103 : : {
104 : 0 : log_sqlite_error(config->db,rc,NULL,"Failed to bind SHA512 checksum");
105 : 0 : status = FAILURE;
106 : : }
107 : : }
108 : :
109 : : /* Copy and bind file metadata */
110 [ + - ]: 2396 : if(SUCCESS & status)
111 : : {
112 : 2396 : rc = sqlite3_bind_blob(insert_stmt,4,&file->stat,sizeof(CmpctStat),NULL);
113 : :
114 [ - + ]: 2396 : if(SQLITE_OK != rc)
115 : : {
116 : 0 : log_sqlite_error(config->db,rc,NULL,"Failed to bind file metadata");
117 : 0 : status = FAILURE;
118 : : }
119 : : }
120 : :
121 : : /* Bind SHA512 context */
122 [ + - ]: 2396 : if(SUCCESS & status)
123 : : {
124 [ + + ]: 2396 : if(file->checksum_offset == 0)
125 : : {
126 : 2391 : rc = sqlite3_bind_null(insert_stmt,5);
127 : : } else {
128 : 5 : rc = sqlite3_bind_blob(insert_stmt,5,&file->mdContext,sizeof(SHA512_Context),NULL);
129 : : }
130 : :
131 [ - + ]: 2396 : if(SQLITE_OK != rc)
132 : : {
133 : 0 : log_sqlite_error(config->db,rc,NULL,"Failed to bind SHA512 context");
134 : 0 : status = FAILURE;
135 : : }
136 : : }
137 : :
138 : : /* Execute prepared statement */
139 [ + - ]: 2396 : if(SUCCESS & status)
140 : : {
141 : 2396 : rc = sqlite3_step(insert_stmt);
142 : :
143 [ - + ]: 2396 : if(rc != SQLITE_DONE)
144 : : {
145 : 0 : log_sqlite_error(config->db,rc,NULL,"Insert statement failed");
146 : 0 : status = FAILURE;
147 : : }
148 : : }
149 : :
150 [ + - ]: 2396 : if(SUCCESS & status)
151 : : {
152 : : /* Reflect changes in global */
153 : 2396 : config->db_primary_file_modified = true;
154 : :
155 : : }
156 : :
157 : 2396 : rc = sqlite3_finalize(insert_stmt);
158 : :
159 [ + - - + ]: 2396 : if(SUCCESS & status && SQLITE_OK != rc)
160 : : {
161 : 0 : log_sqlite_error(config->db,rc,NULL,"Failed to finalize insert statement");
162 : 0 : status = FAILURE;
163 : : }
164 : :
165 : 2396 : provide(status);
166 : : }
|