use crate::LixError;
use crate::branch::{
BranchLifecycle, BranchOperation, BranchReferenceRole, branch_descriptor_stage_row,
branch_ref_stage_row,
};
use crate::storage_adapter::Storage;
use crate::transaction_types::{RawWriteBatch, TransactionWrite, TransactionWriteMode};
use super::context::SessionContext;
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct CreateBranchOptions {
pub id: Option<String>,
pub name: String,
pub from_commit_id: Option<String>,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct CreateBranchReceipt {
pub id: String,
pub name: String,
pub hidden: bool,
pub commit_id: String,
}
impl<StorageImpl> SessionContext<StorageImpl>
where
StorageImpl: Storage + Clone + Send + Sync + 'static,
{
pub async fn create_branch(
&self,
options: CreateBranchOptions,
) -> Result<CreateBranchReceipt, LixError> {
self.with_write_transaction_lending(async move |transaction| {
let CreateBranchOptions {
id,
name,
from_commit_id,
} = options;
let branch_id =
id.unwrap_or_else(|| transaction.functions().call_uuid_v7().to_string());
let explicit_historical_source = from_commit_id.is_some();
let source_head = if let Some(from_commit_id) = from_commit_id {
let from_commit_id = BranchLifecycle::parse_commit_id(
&from_commit_id,
BranchOperation::CreateBranch,
BranchReferenceRole::CommitSource,
)?;
let mut commit_graph = transaction.commit_graph_reader().await;
let commit = BranchLifecycle::require_existing_commit(
&mut commit_graph,
from_commit_id,
BranchOperation::CreateBranch,
BranchReferenceRole::CommitSource,
)
.await?;
commit.commit_id
} else {
let active_branch_id = transaction.active_branch_id().to_string();
let reader = transaction.branch_ref_reader().await;
BranchLifecycle::new(&reader)
.require_existing_commit_id(
&active_branch_id,
BranchOperation::CreateBranch,
BranchReferenceRole::Source,
)
.await?
};
let mut rows = RawWriteBatch::with_capacity(2);
rows.push(branch_descriptor_stage_row(&branch_id, &name, false));
rows.push(branch_ref_stage_row(&branch_id, &source_head));
transaction
.stage_write(TransactionWrite::Rows {
mode: TransactionWriteMode::Insert,
rows,
})
.await?;
if explicit_historical_source {
transaction.stage_branch_checkpoint_replacement_resolution(
branch_id.clone(),
source_head,
)?;
}
Ok(CreateBranchReceipt {
id: branch_id,
name,
hidden: false,
commit_id: source_head.to_string(),
})
})
.await
}
}