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,
)
| 2375 | /// let result = repo.insert_from_view(options)?; |
| 2376 | /// ``` |
| 2377 | pub fn insert_from_view( |
| 2378 | &self, |
| 2379 | options: CrossViewInsertOptions, |
| 2380 | ) -> Result<CrossViewInsertOutcome, RepositoryError> { |
| 2381 | let trace_insert = std::env::var_os("ATOMIC_TRACE_INSERT").is_some(); |
| 2382 | let t0 = std::time::Instant::now(); |
| 2383 | |
| 2384 | let mut outcome = CrossViewInsertOutcome::new(); |
| 2385 | outcome.was_dry_run = options.dry_run; |
| 2386 | |
| 2387 | // Determine which changes to consider |
| 2388 | let source_changes = if !options.only_changes.is_empty() { |
| 2389 | // Use only specified changes |
| 2390 | options.only_changes.clone() |
| 2391 | } else if let Some(ref tag_name) = options.up_to_tag { |
| 2392 | // Get changes up to the tag |
| 2393 | self.get_changes_up_to_tag(tag_name, Some(&options.from_view))? |
| 2394 | } else { |
| 2395 | // Get all changes from source view |
| 2396 | self.get_view_changes(Some(&options.from_view))? |
| 2397 | .into_iter() |
| 2398 | .map(|(_, hash)| hash) |
| 2399 | .collect() |
| 2400 | }; |
| 2401 | |
| 2402 | if trace_insert { |
| 2403 | eprintln!( |
| 2404 | "[insert_from_view] start from={} to={} source_changes={}", |
| 2405 | options.from_view, |
| 2406 | options.to_view, |
| 2407 | source_changes.len(), |
| 2408 | ); |
| 2409 | eprintln!( |
| 2410 | "[insert_from_view] source_changes collected count={} elapsed={:?}", |
| 2411 | source_changes.len(), |
| 2412 | t0.elapsed(), |
| 2413 | ); |
| 2414 | } |
| 2415 | |
| 2416 | // Filter to changes not already in target |
| 2417 | let txn = self |
| 2418 | .pristine |
| 2419 | .read_txn() |
| 2420 | .map_err(|e| RepositoryError::Database(e.to_string()))?; |
| 2421 | |
| 2422 | let to_view = txn |
| 2423 | .get_view(&options.to_view) |
| 2424 | .map_err(|e| RepositoryError::Database(e.to_string()))? |
| 2425 | .ok_or_else(|| RepositoryError::ViewNotFound { |
| 2426 | name: options.to_view.clone(), |
| 2427 | })?; |
| 2428 | |
| 2429 | let missing = filter_missing_in_view(&txn, &to_view, &source_changes) |
| 2430 | .map_err(|e| RepositoryError::Apply(e.to_string()))?; |
| 2431 | |
| 2432 | // Track skipped changes |
| 2433 | let missing_set: std::collections::HashSet<_> = missing.iter().collect(); |
| 2434 | for hash in &source_changes { |