use core::ops::Range;
use anyhow::{Error, Result};
use gen_core::region::Region;
use gen_models::{
db::DbContext,
errors::OperationError,
operations::OperationInfo,
session_operations::{end_operation, start_operation},
};
use thiserror::Error;
use crate::{commands::get_default_collection, graphs::operators::derive_chunks};
#[derive(Debug, Error, PartialEq)]
pub enum DeriveSubgraphOperationError {
#[error("Operation Error: {0}")]
OperationError(#[from] OperationError),
#[error("Invalid region boundary: {0}")]
RegionBoundary(String),
}
pub fn derive_subgraph_operation(
db_context: &DbContext,
name: Option<String>,
sample: String,
new_sample: String,
region: String,
backbone: Option<String>,
) -> Result<(), Error> {
let operation_conn = db_context.operations().conn();
let graph_conn = db_context.graph().conn();
let mut session = start_operation(graph_conn);
graph_conn.execute("BEGIN TRANSACTION", [])?;
operation_conn.execute("BEGIN TRANSACTION", [])?;
let collection_name = &(match name {
Some(collection) => collection,
None => get_default_collection(operation_conn),
});
let sample_name = sample.clone();
let new_sample_name = new_sample.clone();
let parsed_region = if let Ok(region) = Region::parse(®ion) {
region
} else {
return Err(Error::msg(format!(
"Failed to parse region string: {}",
region
)));
};
let start_coordinate = parsed_region.start;
let end_coordinate = parsed_region.end;
if let Err(err) = derive_chunks(
db_context,
collection_name,
sample_name.as_str(),
&new_sample_name,
&parsed_region.name.to_string(),
backbone.as_deref(),
vec![Range {
start: start_coordinate,
end: end_coordinate,
}],
None,
true,
) {
graph_conn.execute("ROLLBACK TRANSACTION;", [])?;
operation_conn.execute("ROLLBACK TRANSACTION;", [])?;
return Err(err.into());
}
let summary_str = format!(" {}: new derived block group", new_sample_name,);
let _op = end_operation(
db_context,
&mut session,
&OperationInfo {
files: vec![],
description: "derive subgraph".to_string(),
},
&summary_str,
None,
)
.map_err(DeriveSubgraphOperationError::OperationError)?;
graph_conn.execute("END TRANSACTION;", [])?;
operation_conn.execute("END TRANSACTION;", [])?;
println!("Derive subgraph succeeded.");
Ok(())
}