Insert changes from one view into another. This is the main method for cross-view operations. It can: - Insert all missing changes from source to target - Insert only changes up to a specific tag - Insert only specific changes # Arguments `options` - Options controlling the cross-view insert # Returns A `CrossViewInsertOutcome` with details about what was inserted. # Example ```rust,ignore
(
&self,
options: CrossViewInsertOptions,
)
| 2331 | /// let result = repo.insert_from_view(options)?; |
| 2332 | /// ``` |
| 2333 | pub fn insert_from_view( |
| 2334 | &self, |
| 2335 | options: CrossViewInsertOptions, |
| 2336 | ) -> Result<CrossViewInsertOutcome, RepositoryError> { |
| 2337 | let trace_insert = std::env::var_os("ATOMIC_TRACE_INSERT").is_some(); |
| 2338 | let t0 = std::time::Instant::now(); |
| 2339 | |
| 2340 | let mut outcome = CrossViewInsertOutcome::new(); |
| 2341 | outcome.was_dry_run = options.dry_run; |
| 2342 | |
| 2343 | // Determine which changes to consider |
| 2344 | let source_changes = if !options.only_changes.is_empty() { |
| 2345 | // Use only specified changes |
| 2346 | options.only_changes.clone() |
| 2347 | } else if let Some(ref tag_name) = options.up_to_tag { |
| 2348 | // Get changes up to the tag |
| 2349 | self.get_changes_up_to_tag(tag_name, Some(&options.from_view))? |
| 2350 | } else { |
| 2351 | // Get all changes from source view |
| 2352 | self.get_view_changes(Some(&options.from_view))? |
| 2353 | .into_iter() |
| 2354 | .map(|(_, hash)| hash) |
| 2355 | .collect() |
| 2356 | }; |
| 2357 | |
| 2358 | if trace_insert { |
| 2359 | eprintln!( |
| 2360 | "[insert_from_view] start from={} to={} source_changes={}", |
| 2361 | options.from_view, |
| 2362 | options.to_view, |
| 2363 | source_changes.len(), |
| 2364 | ); |
| 2365 | eprintln!( |
| 2366 | "[insert_from_view] source_changes collected count={} elapsed={:?}", |
| 2367 | source_changes.len(), |
| 2368 | t0.elapsed(), |
| 2369 | ); |
| 2370 | } |
| 2371 | |
| 2372 | // Filter to changes not already in target |
| 2373 | let txn = self |
| 2374 | .pristine |
| 2375 | .read_txn() |
| 2376 | .map_err(|e| RepositoryError::Database(e.to_string()))?; |
| 2377 | |
| 2378 | let to_view = txn |
| 2379 | .get_view(&options.to_view) |
| 2380 | .map_err(|e| RepositoryError::Database(e.to_string()))? |
| 2381 | .ok_or_else(|| RepositoryError::ViewNotFound { |
| 2382 | name: options.to_view.clone(), |
| 2383 | })?; |
| 2384 | |
| 2385 | let missing = filter_missing_in_view(&txn, &to_view, &source_changes) |
| 2386 | .map_err(|e| RepositoryError::Apply(e.to_string()))?; |
| 2387 | |
| 2388 | // Track skipped changes |
| 2389 | let missing_set: std::collections::HashSet<_> = missing.iter().collect(); |
| 2390 | for hash in &source_changes { |