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] 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 : 1569 : 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 : : /* Status returned by this function through provide()
40 : : Default value assumes successful completion */
41 : 1569 : Return status = SUCCESS;
42 : :
43 : : /* Skip database operations in dry run mode --dry-run */
44 [ + + ]: 1569 : if(config->dry_run == true)
45 : : {
46 : 80 : provide(status);
47 : : }
48 : :
49 : 1489 : int rc = 0;
50 : :
51 : 1489 : 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 : 1489 : 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 : 1489 : rc = sqlite3_prepare_v2(config->db,insert_sql,-1,&insert_stmt,NULL);
61 : :
62 [ - + ]: 1489 : 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 [ + - ]: 1489 : if(SUCCESS == status)
70 : : {
71 [ + + ]: 1489 : if(*offset == 0)
72 : : {
73 : 1487 : rc = sqlite3_bind_null(insert_stmt,1);
74 : : } else {
75 : 2 : rc = sqlite3_bind_int64(insert_stmt,1,*offset);
76 : : }
77 : :
78 [ - + ]: 1489 : 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 [ + - ]: 1489 : if(SUCCESS == status)
87 : : {
88 : 1489 : rc = sqlite3_bind_text(insert_stmt,2,relative_path,(int)strlen(relative_path),NULL);
89 : :
90 [ - + ]: 1489 : 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 [ + - ]: 1489 : if(SUCCESS == status)
99 : : {
100 [ + + + + : 1489 : if(*offset == 0 && *zero_size_file == false && *wrong_file_type == false)
+ - ]
101 : : {
102 : 1485 : rc = sqlite3_bind_blob(insert_stmt,3,sha512,SHA512_DIGEST_LENGTH,NULL);
103 : : } else {
104 : 4 : rc = sqlite3_bind_null(insert_stmt,3);
105 : : }
106 : :
107 [ - + ]: 1489 : 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 [ + - ]: 1489 : if(SUCCESS == status)
116 : : {
117 : 1489 : rc = sqlite3_bind_blob(insert_stmt,4,stat,sizeof(CmpctStat),NULL);
118 : :
119 [ - + ]: 1489 : 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 [ + - ]: 1489 : if(SUCCESS == status)
128 : : {
129 [ + + ]: 1489 : if(*offset == 0)
130 : : {
131 : 1487 : rc = sqlite3_bind_null(insert_stmt,5);
132 : : } else {
133 : 2 : rc = sqlite3_bind_blob(insert_stmt,5,mdContext,sizeof(SHA512_Context),NULL);
134 : : }
135 : :
136 [ - + ]: 1489 : 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 [ + - ]: 1489 : if(SUCCESS == status)
145 : : {
146 : 1489 : rc = sqlite3_step(insert_stmt);
147 : :
148 [ - + ]: 1489 : 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 [ + - ]: 1489 : if(SUCCESS == status)
156 : : {
157 : : /* Reflect changes in global */
158 : 1489 : config->db_primary_file_modified = true;
159 : :
160 : : }
161 : :
162 : 1489 : sqlite3_finalize(insert_stmt);
163 : :
164 : 1489 : provide(status);
165 : : }
|