From 26463c037bd5e20b6b03cbe95e7f72e72b19ab7f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fern=C3=A1ndez?= Date: Sat, 4 Jan 2025 23:15:34 +0100 Subject: [PATCH] Changed DBFile ID attribute --- src/db.rs | 86 ++++++++++++++++++++++-------------------------- src/dbfile.rs | 13 ++++---- src/hashevent.rs | 27 ++++++++++----- src/monitor.rs | 2 +- src/scanner.rs | 33 ++++++++----------- 5 files changed, 78 insertions(+), 83 deletions(-) diff --git a/src/db.rs b/src/db.rs index 7ddcc66..96e4f2b 100644 --- a/src/db.rs +++ b/src/db.rs @@ -3,8 +3,9 @@ use crate::appconfig; use crate::utils; use crate::dbfile::*; +use crate::appconfig::AppConfig; -use rusqlite::{Connection, Error}; +use rusqlite::{Connection, Error, params}; use rusqlite::Error::QueryReturnedNoRows; use std::path::Path; use log::*; @@ -87,13 +88,11 @@ impl DB { let connection = self.open(); let result = connection.execute( "CREATE TABLE IF NOT EXISTS files ( - dbid INTEGER PRIMARY KEY, id TEXT PRIMARY KEY, timestamp TEXT NOT NULL, hash TEXT NOT NULL, path TEXT NOT NULL UNIQUE, - size INTEGER, - PRIMARY KEY(dbid, id) )", + size INTEGER)", (), ); match result { @@ -108,8 +107,8 @@ impl DB { pub fn insert_file(&self, file: DBFile) { let connection = self.open(); let result = connection.execute( - "INSERT INTO files (timestamp, hash, path, size) VALUES (?1, ?2, ?3, ?4)", - (file.timestamp, file.hash, file.path, file.size) + "INSERT INTO files (id, timestamp, hash, path, size) VALUES (?1, ?2, ?3, ?4, ?5)", + (file.id, file.timestamp, file.hash, file.path, file.size) ); match result { Ok(_) => debug!("Inserted new file in DB"), @@ -126,12 +125,11 @@ impl DB { "SELECT * FROM files WHERE path = ?1 LIMIT 1", [path.clone()], |row| Ok(DBFile { - dbid: row.get(0).unwrap(), - id: row.get(1).unwrap(), - timestamp: row.get(2).unwrap(), - hash: row.get(3).unwrap(), - path: row.get(4).unwrap(), - size: row.get(5).unwrap() + id: row.get(0).unwrap(), + timestamp: row.get(1).unwrap(), + hash: row.get(2).unwrap(), + path: row.get(3).unwrap(), + size: row.get(4).unwrap() }) ); @@ -154,18 +152,17 @@ impl DB { // ------------------------------------------------------------------------ - pub fn get_file_by_id(&self, dbid: u64) -> DBFile { + pub fn get_file_by_id(&self, id: String) -> DBFile { let connection = self.open(); let data = connection.query_row( - "SELECT * FROM files WHERE dbid = ?1 LIMIT 1", - [dbid], + "SELECT * FROM files WHERE id = ?1 LIMIT 1", + [id], |row| Ok(DBFile { - dbid: row.get(0).unwrap(), - id: row.get(1).unwrap(), - timestamp: row.get(2).unwrap(), - hash: row.get(3).unwrap(), - path: row.get(4).unwrap(), - size: row.get(5).unwrap() + id: row.get(0).unwrap(), + timestamp: row.get(1).unwrap(), + hash: row.get(2).unwrap(), + path: row.get(3).unwrap(), + size: row.get(4).unwrap() }) ).unwrap(); @@ -175,32 +172,28 @@ impl DB { // ------------------------------------------------------------------------ - pub fn update_file(&self, dbfile: DBFile, timestamp: Option, hash: Option, size: Option) { + pub fn update_file(&self, cfg: AppConfig, dbfile: DBFile) -> Option{ let connection = self.open(); + let current_dbfile = DBFile::new(cfg, &dbfile.path, Some(dbfile.id)); - let timestamp_str = match timestamp { - Some(t) => format!("timestamp = '{}'", t), - None => String::new() - }; - let hash_str = match hash { - Some(h) => format!("hash = '{}'", h), - None => String::new() - }; - let size_str = match size { - Some(s) => format!("size = '{}'", s), - None => String::new() - }; - - let query = format!("UPDATE files SET {}, {}, {} WHERE dbid = {}", - timestamp_str, hash_str, size_str, dbfile.dbid); + let query = "UPDATE files SET timestamp = ?1, hash = ?2, size = ?3 WHERE id = ?4"; let mut statement = connection.prepare(&query).unwrap(); - let result = statement.execute([]); + let result = statement.execute(params![ + current_dbfile.timestamp, + current_dbfile.hash, + current_dbfile.size, + current_dbfile.id]); match result { - Ok(_v) => debug!("File '{}', updated with new information.", dbfile.path), - Err(e) => error!("Cannot update file '{}' information, Error: {:?}", dbfile.path, e) + Ok(_v) => { + debug!("File '{}', updated with new information.", dbfile.path); + Some(current_dbfile) + }, + Err(e) => { + error!("Cannot update file '{}' information, Error: {:?}", dbfile.path, e); + None + } } - } // ------------------------------------------------------------------------ @@ -211,12 +204,11 @@ impl DB { "SELECT * from files").unwrap(); let files = query.query_map([], |row|{ Ok(DBFile { - dbid: row.get(0).unwrap(), - id: row.get(1).unwrap(), - timestamp: row.get(2).unwrap(), - hash: row.get(3).unwrap(), - path: row.get(4).unwrap(), - size: row.get(5).unwrap(), + id: row.get(0).unwrap(), + timestamp: row.get(1).unwrap(), + hash: row.get(2).unwrap(), + path: row.get(3).unwrap(), + size: row.get(4).unwrap(), }) }).unwrap(); diff --git a/src/dbfile.rs b/src/dbfile.rs index 69422cd..e2fc1fe 100644 --- a/src/dbfile.rs +++ b/src/dbfile.rs @@ -15,7 +15,6 @@ pub struct DBFileError { } pub struct DBFile { - pub dbid: u64, pub id: String, pub timestamp: String, pub hash: String, @@ -67,7 +66,6 @@ impl fmt::Debug for DBFileError { impl fmt::Debug for DBFile { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result{ f.debug_tuple("") - .field(&self.dbid) .field(&self.id) .field(&self.timestamp) .field(&self.hash) @@ -88,7 +86,7 @@ impl fmt::Display for DBFile { // ---------------------------------------------------------------------------- impl DBFile { - pub fn new(cfg: AppConfig, path: &str) -> Self { + pub fn new(cfg: AppConfig, path: &str, id: Option) -> Self { let size = Path::new(path).metadata().unwrap().len(); let hash = match cfg.clone().checksum_method.as_str() { "Partial" => hash::get_partial_checksum( @@ -101,9 +99,13 @@ impl DBFile { Sha256::new()) }; + let target_id = match id { + Some(data) => data, + None => utils::get_uuid() + }; + DBFile { - dbid: 0, - id: utils::get_uuid(), + id: target_id, timestamp: utils::get_current_time_millis(), hash, path: String::from(path), @@ -115,7 +117,6 @@ impl DBFile { pub fn clone(&self) -> Self { DBFile { - dbid: self.dbid, id: self.id.clone(), timestamp: self.timestamp.clone(), hash: self.hash.clone(), diff --git a/src/hashevent.rs b/src/hashevent.rs index 6ffda98..bc16d75 100644 --- a/src/hashevent.rs +++ b/src/hashevent.rs @@ -12,13 +12,17 @@ use reqwest::Client; use std::time::Duration; pub struct HashEvent { - dbfile: DBFile + //dbfile: DBFile, + previous_dbfile: DBFile, + current_dbfile: DBFile, + //operation: String } impl HashEvent { - pub fn new(dbfile: DBFile) -> Self { + pub fn new(previous_dbfile: DBFile, current_dbfile: DBFile) -> Self { HashEvent { - dbfile + previous_dbfile, + current_dbfile } } @@ -72,7 +76,7 @@ impl HashEvent { } // Elastic endpoint integration } else { - let request_url = format!("{}/{}/_doc/{}", cfg.endpoint_address, index, self.dbfile.id); + let request_url = format!("{}/{}/_doc/{}", cfg.endpoint_address, index, self.current_dbfile.id); let client = Client::builder() .danger_accept_invalid_certs(cfg.insecure) .timeout(Duration::from_secs(30)) @@ -113,11 +117,16 @@ impl HashEvent { fn get_json(&self) -> serde_json::Value { json!({ - "dbfile.id": self.dbfile.id.clone(), - "dbfile.timestamp": self.dbfile.timestamp.clone(), - "dbfile.hash": self.dbfile.hash.clone(), - "dbfile.path": self.dbfile.path.clone(), - "dbfile.size": self.dbfile.size.clone() + "previous_dbfile.id": self.previous_dbfile.id.clone(), + "previous_dbfile.timestamp": self.previous_dbfile.timestamp.clone(), + "previous_dbfile.hash": self.previous_dbfile.hash.clone(), + "previous_dbfile.path": self.previous_dbfile.path.clone(), + "previous_dbfile.size": self.previous_dbfile.size.clone(), + "current_dbfile.id": self.current_dbfile.id.clone(), + "current_dbfile.timestamp": self.current_dbfile.timestamp.clone(), + "current_dbfile.hash": self.current_dbfile.hash.clone(), + "current_dbfile.path": self.current_dbfile.path.clone(), + "current_dbfile.size": self.current_dbfile.size.clone() }) } } \ No newline at end of file diff --git a/src/monitor.rs b/src/monitor.rs index b808600..f980f65 100644 --- a/src/monitor.rs +++ b/src/monitor.rs @@ -133,7 +133,7 @@ pub async fn monitor( Ok(_d) => { debug!("Monitoring '{}' path.", path); debug!("Starting file scan to create hash database."); - scanner::first_scan(cfg.clone(), String::from(path)); + scanner::first_scan(cfg.clone(), String::from(path)).await; debug!("Path '{}' scanned all files are hashed in DB.", path); }, Err(e) => warn!("Could not monitor given path '{}', description: {}", path, e) diff --git a/src/scanner.rs b/src/scanner.rs index f3c5050..c9329fc 100644 --- a/src/scanner.rs +++ b/src/scanner.rs @@ -2,16 +2,12 @@ use crate::db; use crate::dbfile::*; -use crate::utils; use crate::appconfig::AppConfig; use crate::hashevent::HashEvent; use walkdir::WalkDir; use log::*; -// Temporal -use tokio::runtime::Runtime; - pub fn scan_path(cfg: AppConfig, root: String) { let db = db::DB::new(); for res in WalkDir::new(root) { @@ -19,9 +15,7 @@ pub fn scan_path(cfg: AppConfig, root: String) { let metadata = entry.metadata().unwrap(); let path = entry.path(); if metadata.clone().is_file(){ - - - let dbfile = DBFile::new(cfg.clone(), path.to_str().unwrap()); + let dbfile = DBFile::new(cfg.clone(), path.to_str().unwrap(), None); db.insert_file(dbfile); } } @@ -29,7 +23,7 @@ pub fn scan_path(cfg: AppConfig, root: String) { // ---------------------------------------------------------------------------- -pub fn check_changes(cfg: AppConfig, root: String) { +pub async fn check_changes(cfg: AppConfig, root: String) { let db = db::DB::new(); for res in WalkDir::new(root) { let entry = res.unwrap(); @@ -43,21 +37,20 @@ pub fn check_changes(cfg: AppConfig, root: String) { let hash = dbfile.get_disk_hash(cfg.clone()); if dbfile.hash != hash { debug!("The file '{}', has changed.", path.display()); - db.update_file( - dbfile.clone(), - Some(utils::get_current_time_millis()), - Some(hash), - Some(metadata.len())); - let event = HashEvent::new(dbfile); - let rt = Runtime::new().unwrap(); - rt.block_on(event.process(cfg.clone())); - // Trigger new event + let current_dbfile = db.update_file(cfg.clone(), dbfile.clone()); + match current_dbfile { + Some(data) => { + let event = HashEvent::new(dbfile, data); + event.process(cfg.clone()).await; + }, + None => debug!("Could not get current DBFile data.") + } } }, Err(e) => { if e.kind() == "DBFileNotFoundError" { debug!("New file '{}' found in directory.", path.display()); - let dbfile = DBFile::new(cfg.clone(), path.to_str().unwrap()); + let dbfile = DBFile::new(cfg.clone(), path.to_str().unwrap(), None); db.insert_file(dbfile); // Trigger new event } else { @@ -71,10 +64,10 @@ pub fn check_changes(cfg: AppConfig, root: String) { // ---------------------------------------------------------------------------- -pub fn first_scan(cfg: AppConfig, root: String) { +pub async fn first_scan(cfg: AppConfig, root: String) { let db = db::DB::new(); if ! db.is_empty() { - check_changes(cfg, root); + check_changes(cfg, root).await; } else { scan_path(cfg, root); }