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,
)
| 2426 | /// let result = repo.insert_from_view(options)?; |
| 2427 | /// ``` |
| 2428 | pub fn insert_from_view( |
| 2429 | &self, |
| 2430 | options: CrossViewInsertOptions, |
| 2431 | ) -> Result<CrossViewInsertOutcome, RepositoryError> { |
| 2432 | let trace_insert = std::env::var_os("ATOMIC_TRACE_INSERT").is_some(); |
| 2433 | let t0 = std::time::Instant::now(); |
| 2434 | |
| 2435 | let mut outcome = CrossViewInsertOutcome::new(); |
| 2436 | outcome.was_dry_run = options.dry_run; |
| 2437 | |
| 2438 | // Determine which changes to consider |
| 2439 | let source_changes = if !options.only_changes.is_empty() { |
| 2440 | // Use only specified changes |
| 2441 | options.only_changes.clone() |
| 2442 | } else if let Some(ref tag_name) = options.up_to_tag { |
| 2443 | // Get changes up to the tag |
| 2444 | self.get_changes_up_to_tag(tag_name, Some(&options.from_view))? |
| 2445 | } else { |
| 2446 | // Get all changes from source view |
| 2447 | self.get_view_changes(Some(&options.from_view))? |
| 2448 | .into_iter() |
| 2449 | .map(|(_, hash)| hash) |
| 2450 | .collect() |
| 2451 | }; |
| 2452 | |
| 2453 | if trace_insert { |
| 2454 | eprintln!( |
| 2455 | "[insert_from_view] start from={} to={} source_changes={}", |
| 2456 | options.from_view, |
| 2457 | options.to_view, |
| 2458 | source_changes.len(), |
| 2459 | ); |
| 2460 | eprintln!( |
| 2461 | "[insert_from_view] source_changes collected count={} elapsed={:?}", |
| 2462 | source_changes.len(), |
| 2463 | t0.elapsed(), |
| 2464 | ); |
| 2465 | } |
| 2466 | |
| 2467 | // Filter to changes not already in target |
| 2468 | let txn = self |
| 2469 | .pristine |
| 2470 | .read_txn() |
| 2471 | .map_err(|e| RepositoryError::Database(e.to_string()))?; |
| 2472 | |
| 2473 | let to_view = txn |
| 2474 | .get_view(&options.to_view) |
| 2475 | .map_err(|e| RepositoryError::Database(e.to_string()))? |
| 2476 | .ok_or_else(|| RepositoryError::ViewNotFound { |
| 2477 | name: options.to_view.clone(), |
| 2478 | })?; |
| 2479 | |
| 2480 | let missing = filter_missing_in_view(&txn, &to_view, &source_changes) |
| 2481 | .map_err(|e| RepositoryError::Apply(e.to_string()))?; |
| 2482 | |
| 2483 | // Track skipped changes |
| 2484 | let missing_set: std::collections::HashSet<_> = missing.iter().collect(); |
| 2485 | for hash in &source_changes { |