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,
)
| 2481 | /// let result = repo.insert_from_view(options)?; |
| 2482 | /// ``` |
| 2483 | pub fn insert_from_view( |
| 2484 | &self, |
| 2485 | options: CrossViewInsertOptions, |
| 2486 | ) -> Result<CrossViewInsertOutcome, RepositoryError> { |
| 2487 | let trace_insert = std::env::var_os("ATOMIC_TRACE_INSERT").is_some(); |
| 2488 | let t0 = std::time::Instant::now(); |
| 2489 | |
| 2490 | let mut outcome = CrossViewInsertOutcome::new(); |
| 2491 | outcome.was_dry_run = options.dry_run; |
| 2492 | |
| 2493 | // Determine which changes to consider |
| 2494 | let source_changes = if !options.only_changes.is_empty() { |
| 2495 | // Use only specified changes |
| 2496 | options.only_changes.clone() |
| 2497 | } else if let Some(ref tag_name) = options.up_to_tag { |
| 2498 | // Get changes up to the tag |
| 2499 | self.get_changes_up_to_tag(tag_name, Some(&options.from_view))? |
| 2500 | } else { |
| 2501 | // Get all changes from source view |
| 2502 | self.get_view_changes(Some(&options.from_view))? |
| 2503 | .into_iter() |
| 2504 | .map(|(_, hash)| hash) |
| 2505 | .collect() |
| 2506 | }; |
| 2507 | |
| 2508 | if trace_insert { |
| 2509 | eprintln!( |
| 2510 | "[insert_from_view] start from={} to={} source_changes={}", |
| 2511 | options.from_view, |
| 2512 | options.to_view, |
| 2513 | source_changes.len(), |
| 2514 | ); |
| 2515 | eprintln!( |
| 2516 | "[insert_from_view] source_changes collected count={} elapsed={:?}", |
| 2517 | source_changes.len(), |
| 2518 | t0.elapsed(), |
| 2519 | ); |
| 2520 | } |
| 2521 | |
| 2522 | // Filter to changes not already in target |
| 2523 | let txn = self |
| 2524 | .pristine |
| 2525 | .read_txn() |
| 2526 | .map_err(|e| RepositoryError::Database(e.to_string()))?; |
| 2527 | |
| 2528 | let to_view = txn |
| 2529 | .get_view(&options.to_view) |
| 2530 | .map_err(|e| RepositoryError::Database(e.to_string()))? |
| 2531 | .ok_or_else(|| RepositoryError::ViewNotFound { |
| 2532 | name: options.to_view.clone(), |
| 2533 | })?; |
| 2534 | |
| 2535 | let missing = filter_missing_in_view(&txn, &to_view, &source_changes) |
| 2536 | .map_err(|e| RepositoryError::Apply(e.to_string()))?; |
| 2537 | |
| 2538 | // Track skipped changes |
| 2539 | let missing_set: std::collections::HashSet<_> = missing.iter().collect(); |
| 2540 | for hash in &source_changes { |