aboutsummaryrefslogtreecommitdiff
path: root/src/database_interaction.c
diff options
context:
space:
mode:
authorThorsten Töpper <atsutane@freethoughts.de>2026-03-01 21:10:48 +0100
committerThorsten Töpper <atsutane@freethoughts.de>2026-03-01 21:10:48 +0100
commitb551c441e10c94ccfe188d9bcc783efe78cd5083 (patch)
treeb5e88509bd6155fb7af9a3e54efcf66adef541a0 /src/database_interaction.c
parent951ba68794bc228e00c40d36cca44c65da69603c (diff)
downloadduplicate_finder-b551c441e10c94ccfe188d9bcc783efe78cd5083.tar.gz
duplicate_finder-b551c441e10c94ccfe188d9bcc783efe78cd5083.tar.bz2
file_processor: Skip files already in the DB with same size and mtime
Diffstat (limited to 'src/database_interaction.c')
-rw-r--r--src/database_interaction.c131
1 files changed, 130 insertions, 1 deletions
diff --git a/src/database_interaction.c b/src/database_interaction.c
index 5188a35..9e29c17 100644
--- a/src/database_interaction.c
+++ b/src/database_interaction.c
@@ -923,6 +923,136 @@ int dbi_insert_fileinfo(struct df_fileinfo *fi) {
return rc;
};
+/**
+ * Fill the given struct (path and filename required) with database content if available.
+ *
+ * This can be used to speed up a rescan if the stat matches and last mtime was before last_seen
+ */
+int dbi_fill_fileinfo(struct df_fileinfo *fi) {
+ int rc = 0;
+ int64_t fname_id, pname_id, existing_entry = 0;
+
+
+ DBCONN_CHECK(-1);
+
+ if (fi == NULL) {
+ LOGERR("ERROR: No fileinfo given.\n");
+ return -1;
+ }
+
+ fname_id = dbi_select_filename_by_name(fi->name);
+ pname_id = dbi_select_path_by_pathname(fi->path);
+
+ /* Any problems with the selects? */
+ if (fname_id <0 || pname_id <0) {
+ DBGTRC("ERROR: abort due to previous error.\n");
+ return -1;
+ }
+
+ /* Abort if no matching entry in the table */
+ existing_entry = dbi_select_fileinfo_by_path_filename_ids(pname_id, fname_id);
+ if (existing_entry < 0) {
+ fi->id = 0;
+ return 0;
+ }
+
+ /* TODO: The following has be moved to a dbi_select_fileinfo_by_id_resolved */
+ rc = dbi_select_fileinfo_by_id_resolved(existing_entry, fi);
+
+ return rc;
+}
+
+
+
+int dbi_select_fileinfo_by_id_resolved(int64_t id, struct df_fileinfo *fi) {
+ int strc = 0;
+ size_t len;
+ char *tmp = NULL;
+ const unsigned char *txt = NULL;
+ sqlite3_stmt *st = select_fileinfo_by_id_resolved;
+
+
+ DBCONN_CHECK(-1);
+
+ if (id <=0) {
+ LOGERR("ERROR: No id given.\n");
+ return -1;
+ }
+
+ if (fi == NULL) {
+ LOGERR("ERROR: No fileinfo struct given.\n");
+ return -1;
+ }
+
+
+ sqlite3_clear_bindings(st);
+ sqlite3_reset(st);
+
+ if (sqlite3_bind_int64(st, 1,id) != SQLITE_OK) {
+ LOGERR("ERROR: Failed to bind id to prepared statement: %s\n", sqlite3_errmsg(dbconn));
+ return -1;
+ }
+
+ strc = sqlite3_step(st);
+
+ if (strc == SQLITE_DONE) {
+ return -1;
+ }
+
+ if (strc != SQLITE_ROW) {
+ LOGERR("ERROR: Failed step: %s\n", sqlite3_errmsg(dbconn));
+ return -1;
+ }
+
+ if (fi->path == NULL) {
+ txt = sqlite3_column_text(st, 0); /* paths.pathname */
+ len = (size_t)sqlite3_column_bytes(st, 0);
+ if ((tmp = calloc(len+1, sizeof(char))) == NULL) {
+ LOGERR("ERROR: Failed to allocate a few bytes memory\n");
+ return -1;
+ }
+ memcpy(tmp, txt, len);
+ fi->path = tmp;
+ }
+
+ if (fi->name == NULL) {
+ txt = sqlite3_column_text(st, 1); /* filenames.name */
+ len = (size_t)sqlite3_column_bytes(st, 1);
+ if ((tmp = calloc(len+1, sizeof(char))) == NULL) {
+ LOGERR("ERROR: Failed to allocate a few bytes memory\n");
+ return -1;
+ }
+ memcpy(tmp, txt, len);
+ fi->path = tmp;
+ }
+
+ txt = sqlite3_column_text(st, 2); /* hashes.blake2 */
+ memcpy(fi->hashes.blake2, txt, DF_STR_SIZE_512);
+ fi->hashes.blake2[DF_STR_SIZE_512] = '\0'; /* array has the additional nul byte space */
+
+ txt = sqlite3_column_text(st, 3); /* hashes.sha256 */
+ memcpy(fi->hashes.sha256, txt, DF_STR_SIZE_256);
+ fi->hashes.sha256[DF_STR_SIZE_256] = '\0'; /* array has the additional nul byte space */
+
+ txt = sqlite3_column_text(st, 4); /* hashes.sha512 */
+ memcpy(fi->hashes.sha512, txt, DF_STR_SIZE_512);
+ fi->hashes.sha512[DF_STR_SIZE_512] = '\0'; /* array has the additional nul byte space */
+
+ /* Ignore the item 5 from the query, it's the filesize we have in the stat struct */
+
+ fi->last_seen = (time_t) sqlite3_column_int64(st, 6); /* last_seen */
+
+ /* struct stat statbuf */
+ memcpy(&(fi->statbuf), sqlite3_column_blob(st, 7), (size_t)sqlite3_column_bytes(st, 7));
+
+ fi->id = id;
+
+ sqlite3_clear_bindings(st);
+ sqlite3_reset(st);
+
+
+ return 0;
+}
/**
* Print the database content to the given filedescriptor in a CSV form which can be processed with grep awk etc.
@@ -1363,7 +1493,6 @@ int dbi_print_filenames(FILE *out) {
#if 0
*select_fileinfo_by_id,
- *select_fileinfo_by_id_resolved,
*select_fileinfo_by_path_id,
*select_fileinfo_by_filename_id,
*select_fileinfo_by_path_filename_ids,