diff --git a/src/modes/save.rs b/src/modes/save.rs index f7ee068..1a63de2 100644 --- a/src/modes/save.rs +++ b/src/modes/save.rs @@ -119,6 +119,9 @@ pub fn mode_save( db::set_item_tags(conn, item.clone(), tags)?; + // Use a transaction for database operations to ensure atomicity + let tx = conn.transaction()?; + let mut item_meta: HashMap = get_meta_from_env(); if let Ok(hostname) = gethostname().into_string() { @@ -132,16 +135,16 @@ pub fn mode_save( item_meta.insert(item.key, item.value); } + let item_id = item.id.ok_or_else(|| anyhow!("Item missing ID"))?; for kv in item_meta.iter() { let meta = db::Meta { - id: item.id.unwrap(), + id: item_id, name: kv.0.to_string(), value: kv.1.to_string(), }; - db::store_meta(conn, meta)?; + db::store_meta(&tx, meta)?; } - let item_id = item.id.ok_or_else(|| anyhow!("Item missing ID"))?; let mut item_path = data_path.clone(); item_path.push(item_id.to_string()); @@ -190,7 +193,7 @@ pub fn mode_save( match meta_plugin.finalize() { Ok(meta_value) => { - if let Err(e) = store_item_meta_value(conn, item.clone(), meta_name.clone(), meta_value) { + if let Err(e) = store_item_meta_value(&tx, item.clone(), meta_name.clone(), meta_value) { eprintln!("Warning: Failed to store meta value for {}: {}", meta_name, e); } } @@ -200,7 +203,10 @@ pub fn mode_save( } } - db::update_item(conn, item.clone())?; + db::update_item(&tx, item.clone())?; + + // Commit the transaction + tx.commit()?; Ok(()) } diff --git a/src/modes/update.rs b/src/modes/update.rs index bea8ebd..9e7a777 100644 --- a/src/modes/update.rs +++ b/src/modes/update.rs @@ -35,9 +35,12 @@ pub fn mode_update( let mut item = item_maybe.expect("Unable to find item in database"); debug!("MAIN: Found item {:?}", item); + // Use a transaction for database operations to ensure atomicity + let tx = conn.transaction()?; + if !tags.is_empty() { debug!("MAIN: Updating item tags"); - db::set_item_tags(conn, item.clone(), tags)?; + db::set_item_tags(&tx, item.clone(), tags)?; } let item_id = item.id.ok_or_else(|| anyhow!("Item missing ID"))?; @@ -59,7 +62,7 @@ pub fn mode_update( debug!("MAIN: Updating stream size of {:?}", item_path); let size = compression_engine.size(item_path.clone())?; item.size = Some(size as i64); - db::update_item(conn, item.clone())?; + db::update_item(&tx, item.clone())?; } else { debug!( "MAIN: Unable to update size of item due to missing file {:?}", @@ -70,7 +73,7 @@ pub fn mode_update( let digest_type = cmd_args_digest_type(cmd, args); let digest_meta = get_digest_type_meta(digest_type.clone()); - let digest_value = db::get_item_meta_value(&conn, &item, digest_meta)?; + let digest_value = db::get_item_meta_value(&tx, &item, digest_meta)?; if digest_value.is_none() || digest_value.unwrap().is_empty() { let item_file_metadata = item_path.metadata(); @@ -97,7 +100,7 @@ pub fn mode_update( debug!("DIGEST: {}", digest_value); // Save digest to meta using the common function - store_item_digest_value(conn, item.clone(), digest_type, digest_value)?; + store_item_digest_value(&tx, item.clone(), digest_type, digest_value)?; } else { debug!( "MAIN: Unable to update digest of item due to missing file {:?}", @@ -110,13 +113,16 @@ pub fn mode_update( debug!("MAIN: Updating item meta"); for kv in args.item.meta.iter() { let meta = db::Meta { - id: item.id.unwrap(), + id: item_id, name: kv.key.to_string(), value: kv.value.to_string(), }; - db::store_meta(conn, meta)?; + db::store_meta(&tx, meta)?; } } + + // Commit the transaction + tx.commit()?; Ok(()) }