Store a pre-built vault entry. Also updates the manifest. This is a lower-level method for internal use and tests where the caller has already constructed a `VaultEntry`. For the common case prefer [`vault_store`](Self::vault_store) which accepts raw parameters.
(
&self,
path: &str,
entry: &VaultEntry,
)
| 229 | /// caller has already constructed a `VaultEntry`. For the common case |
| 230 | /// prefer [`vault_store`](Self::vault_store) which accepts raw parameters. |
| 231 | pub fn vault_store_entry( |
| 232 | &self, |
| 233 | path: &str, |
| 234 | entry: &VaultEntry, |
| 235 | ) -> Result<Hash, RepositoryError> { |
| 236 | let content_hash = Hash::from_bytes(entry.content_hash); |
| 237 | let now = chrono::Utc::now().to_rfc3339(); |
| 238 | |
| 239 | let mut txn = self |
| 240 | .pristine |
| 241 | .write_txn() |
| 242 | .map_err(|e| RepositoryError::Database(e.to_string()))?; |
| 243 | use atomic_core::pristine::{KgMutTxnT, VaultMutTxnT, VaultTxnT}; |
| 244 | |
| 245 | let previous_entry = txn |
| 246 | .get_vault_entry(path) |
| 247 | .map_err(|e| RepositoryError::Database(e.to_string()))?; |
| 248 | let cascade_updates = match previous_entry.as_ref() { |
| 249 | Some(previous) if previous.entry_type != entry.entry_type => { |
| 250 | unlink_goal_from_intent_entries(&mut txn, path, previous, &now)? |
| 251 | } |
| 252 | _ => Vec::new(), |
| 253 | }; |
| 254 | if let Some(previous_entry_type) = previous_entry |
| 255 | .as_ref() |
| 256 | .map(|previous| previous.entry_type) |
| 257 | .filter(|previous| *previous != entry.entry_type) |
| 258 | { |
| 259 | txn.init_kg() |
| 260 | .map_err(|e| RepositoryError::Database(e.to_string()))?; |
| 261 | txn.del_kg_node(&super::vault_triples::entry_subject( |
| 262 | path, |
| 263 | previous_entry_type, |
| 264 | )) |
| 265 | .map_err(|e| RepositoryError::Database(e.to_string()))?; |
| 266 | } |
| 267 | |
| 268 | txn.put_vault_entry(path, entry) |
| 269 | .map_err(|e| RepositoryError::Database(e.to_string()))?; |
| 270 | |
| 271 | let mut manifest = txn |
| 272 | .get_vault_manifest() |
| 273 | .map_err(|e| RepositoryError::Database(e.to_string()))?; |
| 274 | update_manifest_for_store(&mut manifest, path, entry, previous_entry.as_ref(), &now); |
| 275 | apply_cascaded_intent_manifest_updates(&mut manifest, &cascade_updates, &now); |
| 276 | txn.put_vault_manifest(&manifest) |
| 277 | .map_err(|e| RepositoryError::Database(e.to_string()))?; |
| 278 | |
| 279 | txn.commit() |
| 280 | .map_err(|e| RepositoryError::Database(e.to_string()))?; |
| 281 | |
| 282 | self.vault_auto_index(path); |
| 283 | for update in cascade_updates { |
| 284 | self.vault_auto_index(&update.path); |
| 285 | if let Err(error) = self.vault_materialize(&update.path) { |
| 286 | log::warn!( |
| 287 | "Failed to materialize Intent '{}' after Goal unlink: {}", |
| 288 | update.path, |