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] offset File offset value, 0 indicates no offset
20 : * @param[in] sha512 SHA512 checksum of the file, NULL if offset is non-zero
21 : * @param[in] stat File metadata structure
22 : * @param[in] mdContext SHA512 context structure, NULL if offset is zero
23 : *
24 : * @return Return status code:
25 : * - SUCCESS: Record inserted successfully
26 : * - FAILURE: Error occurred during insertion
27 : *
28 : * @note In dry run mode, the function returns SUCCESS without modifying the database
29 : */
30 1028 : Return db_insert_the_record(
31 : const char *relative_path,
32 : const sqlite3_int64 *offset,
33 : const unsigned char *sha512,
34 : const CmpctStat *stat,
35 : const SHA512_Context *mdContext,
36 : const bool *zero_size_file,
37 : const bool *wrong_file_type)
38 : {
39 : /// The status that will be passed to return() before exiting.
40 : /// By default, the function worked without errors.
41 1028 : Return status = SUCCESS;
42 :
43 : /* Skip database operations in dry run mode --dry-run */
44 1028 : if(config->dry_run == true)
45 : {
46 32 : provide(status);
47 : }
48 :
49 996 : int rc = 0;
50 :
51 996 : sqlite3_stmt *insert_stmt = NULL;
52 :
53 : #if 0 // Old multiPATH solution
54 : const char *insert_sql = "INSERT INTO files (offset,path_prefix_index,relative_path,sha512,stat,mdContext) VALUES (?1, ?2, ?3, ?4, ?5, ?6);";
55 : #else
56 996 : const char *insert_sql = "INSERT INTO files (offset,relative_path,sha512,stat,mdContext) VALUES (?1, ?2, ?3, ?4, ?5);";
57 : #endif
58 :
59 : /* Prepare SQL statement */
60 996 : rc = sqlite3_prepare_v2(config->db,insert_sql,-1,&insert_stmt,NULL);
61 :
62 996 : if(SQLITE_OK != rc)
63 : {
64 0 : log_sqlite_error(config->db,rc,NULL,"Failed to prepare insert statement %s",insert_sql);
65 0 : status = FAILURE;
66 : }
67 :
68 : /* Bind offset value */
69 996 : if(SUCCESS == status)
70 : {
71 996 : if(*offset == 0)
72 : {
73 996 : rc = sqlite3_bind_null(insert_stmt,1);
74 : } else {
75 0 : rc = sqlite3_bind_int64(insert_stmt,1,*offset);
76 : }
77 :
78 996 : if(SQLITE_OK != rc)
79 : {
80 0 : log_sqlite_error(config->db,rc,NULL,"Failed to bind offset value");
81 0 : status = FAILURE;
82 : }
83 : }
84 :
85 : /* Bind relative path */
86 996 : if(SUCCESS == status)
87 : {
88 996 : rc = sqlite3_bind_text(insert_stmt,2,relative_path,(int)strlen(relative_path),NULL);
89 :
90 996 : if(SQLITE_OK != rc)
91 : {
92 0 : log_sqlite_error(config->db,rc,NULL,"Failed to bind relative path");
93 0 : status = FAILURE;
94 : }
95 : }
96 :
97 : /* Bind SHA512 checksum */
98 996 : if(SUCCESS == status)
99 : {
100 996 : if(*offset == 0 && *zero_size_file == false && *wrong_file_type == false)
101 : {
102 994 : rc = sqlite3_bind_blob(insert_stmt,3,sha512,SHA512_DIGEST_LENGTH,NULL);
103 : } else {
104 2 : rc = sqlite3_bind_null(insert_stmt,3);
105 : }
106 :
107 996 : if(SQLITE_OK != rc)
108 : {
109 0 : log_sqlite_error(config->db,rc,NULL,"Failed to bind SHA512 checksum");
110 0 : status = FAILURE;
111 : }
112 : }
113 :
114 : /* Copy and bind file metadata */
115 996 : if(SUCCESS == status)
116 : {
117 996 : rc = sqlite3_bind_blob(insert_stmt,4,stat,sizeof(CmpctStat),NULL);
118 :
119 996 : if(SQLITE_OK != rc)
120 : {
121 0 : log_sqlite_error(config->db,rc,NULL,"Failed to bind file metadata");
122 0 : status = FAILURE;
123 : }
124 : }
125 :
126 : /* Bind SHA512 context */
127 996 : if(SUCCESS == status)
128 : {
129 996 : if(*offset == 0)
130 : {
131 996 : rc = sqlite3_bind_null(insert_stmt,5);
132 : } else {
133 0 : rc = sqlite3_bind_blob(insert_stmt,5,mdContext,sizeof(SHA512_Context),NULL);
134 : }
135 :
136 996 : if(SQLITE_OK != rc)
137 : {
138 0 : log_sqlite_error(config->db,rc,NULL,"Failed to bind SHA512 context");
139 0 : status = FAILURE;
140 : }
141 : }
142 :
143 : /* Execute prepared statement */
144 996 : if(SUCCESS == status)
145 : {
146 996 : rc = sqlite3_step(insert_stmt);
147 :
148 996 : if(rc != SQLITE_DONE)
149 : {
150 0 : log_sqlite_error(config->db,rc,NULL,"Insert statement failed");
151 0 : status = FAILURE;
152 : }
153 : }
154 :
155 996 : if(SUCCESS == status)
156 : {
157 : /* Reflect changes in global */
158 996 : config->db_primary_file_modified = true;
159 :
160 : }
161 :
162 996 : sqlite3_finalize(insert_stmt);
163 :
164 996 : provide(status);
165 : }
|