From fa4834bc1286ca0687c5a5940ba7d9f7ed12dd7a Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Sat, 28 Sep 2024 00:22:27 +0700 Subject: [PATCH] feat: added a convenience method that will return an existing item during a check for insertion --- grovedb/src/operations/insert/mod.rs | 40 ++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/grovedb/src/operations/insert/mod.rs b/grovedb/src/operations/insert/mod.rs index af7629ae..0177b1bc 100644 --- a/grovedb/src/operations/insert/mod.rs +++ b/grovedb/src/operations/insert/mod.rs @@ -486,6 +486,7 @@ impl GroveDb { } /// Insert if not exists + /// The bool return is whether we were able to insert pub fn insert_if_not_exists<'b, B, P>( &self, path: P, @@ -522,6 +523,45 @@ impl GroveDb { } } + /// Insert if not exists + /// If the item does exist return it + pub fn insert_if_not_exists_return_existing_element<'b, B, P>( + &self, + path: P, + key: &[u8], + element: Element, + transaction: TransactionArg, + grove_version: &GroveVersion, + ) -> CostResult, Error> + where + B: AsRef<[u8]> + 'b, + P: Into>, + { + check_grovedb_v0_with_cost!( + "insert_if_not_exists", + grove_version + .grovedb_versions + .operations + .insert + .insert_if_not_exists + ); + + let mut cost = OperationCost::default(); + let subtree_path: SubtreePath<_> = path.into(); + + let previous_element = cost_return_on_error!( + &mut cost, + self.get_raw_optional(subtree_path.clone(), key, transaction, grove_version) + ); + if previous_element.is_some() { + Ok(previous_element).wrap_with_cost(cost) + } else { + self.insert(subtree_path, key, element, None, transaction, grove_version) + .map_ok(|_| None) + .add_cost(cost) + } + } + /// Insert if the value changed /// We return if the value was inserted /// If the value was changed then we return the previous element