Branch data Line data Source code
1 : : /**
2 : : * @file db_insert_the_record.c
3 : : * @brief Implementation of database record insertion functionality
4 : : * @details Contains functions for inserting new records into the SQLite database
5 : : * including file metadata, checksums and offset information
6 : : */
7 : :
8 : : #include "precizer.h"
9 : :
10 : : /**
11 : : * @brief Inserts a new record into the database
12 : : *
13 : : * @details This function inserts information about a file including its relative path,
14 : : * file offset, SHA512 checksum, file metadata (stat), and SHA512 context
15 : : * into the SQLite database. The function handles both complete file records
16 : : * and partial records where some fields may be NULL.
17 : : *
18 : : * @param[in] relative_path Path to the file relative to the root directory
19 : : * @param[in] file Per-file state object. Uses checksum_offset, sha512, stat,
20 : : * mdContext, zero_size_file, and wrong_file_type when binding
21 : : * the row values
22 : : *
23 : : * @return Return status code:
24 : : * - SUCCESS: Record inserted successfully
25 : : * - FAILURE: Error occurred during insertion
26 : : *
27 : : * @note In dry run mode, the function returns SUCCESS without modifying the database
28 : : */
29 : 1979 : Return db_insert_the_record(
30 : : const char *relative_path,
31 : : const File *file)
32 : : {
33 : : /* Status returned by this function through provide()
34 : : Default value assumes successful completion */
35 : 1979 : Return status = SUCCESS;
36 : :
37 : : /* Skip database operations in dry run mode --dry-run */
38 [ + + ]: 1979 : if(config->dry_run == true)
39 : : {
40 : 80 : provide(status);
41 : : }
42 : :
43 : 1899 : int rc = 0;
44 : :
45 : 1899 : sqlite3_stmt *insert_stmt = NULL;
46 : :
47 : : #if 0 // Old multiPATH solution
48 : : const char *insert_sql = "INSERT INTO files (offset,path_prefix_index,relative_path,sha512,stat,mdContext) VALUES (?1, ?2, ?3, ?4, ?5, ?6);";
49 : : #else
50 : 1899 : const char *insert_sql = "INSERT INTO files (offset,relative_path,sha512,stat,mdContext) VALUES (?1, ?2, ?3, ?4, ?5);";
51 : : #endif
52 : :
53 : : /* Prepare SQL statement */
54 : 1899 : rc = sqlite3_prepare_v2(config->db,insert_sql,-1,&insert_stmt,NULL);
55 : :
56 [ - + ]: 1899 : if(SQLITE_OK != rc)
57 : : {
58 : 0 : log_sqlite_error(config->db,rc,NULL,"Failed to prepare insert statement %s",insert_sql);
59 : 0 : status = FAILURE;
60 : : }
61 : :
62 : : /* Bind offset value */
63 [ + - ]: 1899 : if(SUCCESS == status)
64 : : {
65 [ + + ]: 1899 : if(file->checksum_offset == 0)
66 : : {
67 : 1897 : rc = sqlite3_bind_null(insert_stmt,1);
68 : : } else {
69 : 2 : rc = sqlite3_bind_int64(insert_stmt,1,file->checksum_offset);
70 : : }
71 : :
72 [ - + ]: 1899 : if(SQLITE_OK != rc)
73 : : {
74 : 0 : log_sqlite_error(config->db,rc,NULL,"Failed to bind offset value");
75 : 0 : status = FAILURE;
76 : : }
77 : : }
78 : :
79 : : /* Bind relative path */
80 [ + - ]: 1899 : if(SUCCESS == status)
81 : : {
82 : 1899 : rc = sqlite3_bind_text(insert_stmt,2,relative_path,(int)strlen(relative_path),NULL);
83 : :
84 [ - + ]: 1899 : 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 : : /* Bind SHA512 checksum */
92 [ + - ]: 1899 : if(SUCCESS == status)
93 : : {
94 [ + + + + : 1899 : if(file->checksum_offset == 0 && file->zero_size_file == false && file->wrong_file_type == false)
+ - ]
95 : : {
96 : 1893 : rc = sqlite3_bind_blob(insert_stmt,3,file->sha512,SHA512_DIGEST_LENGTH,NULL);
97 : : } else {
98 : 6 : rc = sqlite3_bind_null(insert_stmt,3);
99 : : }
100 : :
101 [ - + ]: 1899 : if(SQLITE_OK != rc)
102 : : {
103 : 0 : log_sqlite_error(config->db,rc,NULL,"Failed to bind SHA512 checksum");
104 : 0 : status = FAILURE;
105 : : }
106 : : }
107 : :
108 : : /* Copy and bind file metadata */
109 [ + - ]: 1899 : if(SUCCESS == status)
110 : : {
111 : 1899 : rc = sqlite3_bind_blob(insert_stmt,4,&file->stat,sizeof(CmpctStat),NULL);
112 : :
113 [ - + ]: 1899 : if(SQLITE_OK != rc)
114 : : {
115 : 0 : log_sqlite_error(config->db,rc,NULL,"Failed to bind file metadata");
116 : 0 : status = FAILURE;
117 : : }
118 : : }
119 : :
120 : : /* Bind SHA512 context */
121 [ + - ]: 1899 : if(SUCCESS == status)
122 : : {
123 [ + + ]: 1899 : if(file->checksum_offset == 0)
124 : : {
125 : 1897 : rc = sqlite3_bind_null(insert_stmt,5);
126 : : } else {
127 : 2 : rc = sqlite3_bind_blob(insert_stmt,5,&file->mdContext,sizeof(SHA512_Context),NULL);
128 : : }
129 : :
130 [ - + ]: 1899 : if(SQLITE_OK != rc)
131 : : {
132 : 0 : log_sqlite_error(config->db,rc,NULL,"Failed to bind SHA512 context");
133 : 0 : status = FAILURE;
134 : : }
135 : : }
136 : :
137 : : /* Execute prepared statement */
138 [ + - ]: 1899 : if(SUCCESS == status)
139 : : {
140 : 1899 : rc = sqlite3_step(insert_stmt);
141 : :
142 [ - + ]: 1899 : if(rc != SQLITE_DONE)
143 : : {
144 : 0 : log_sqlite_error(config->db,rc,NULL,"Insert statement failed");
145 : 0 : status = FAILURE;
146 : : }
147 : : }
148 : :
149 [ + - ]: 1899 : if(SUCCESS == status)
150 : : {
151 : : /* Reflect changes in global */
152 : 1899 : config->db_primary_file_modified = true;
153 : :
154 : : }
155 : :
156 : 1899 : sqlite3_finalize(insert_stmt);
157 : :
158 : 1899 : provide(status);
159 : : }
|