use super::WriteTransaction;
use crate::core::error::{Result, TransactionError};
pub(crate) fn detect_conflicts(tx: &WriteTransaction) -> Result<()> {
for write in tx.buffer.operations() {
match write {
crate::api::transaction::BufferedWrite::UpdateNode { node_id, .. } => {
match tx.current.get_node(*node_id) {
Ok(current_node) => {
if let Some(commit_ts) = current_node.metadata.commit_timestamp
&& commit_ts > tx.snapshot.snapshot_timestamp
{
return Err(TransactionError::SerializationFailure {
entity: format!("{:?}", node_id),
reason: format!(
"Version committed at {} after snapshot at {}",
commit_ts, tx.snapshot.snapshot_timestamp
),
}
.into());
}
}
Err(_) => {
return Err(TransactionError::SerializationFailure {
entity: format!("{:?}", node_id),
reason: "Node was deleted by another transaction".to_string(),
}
.into());
}
}
}
crate::api::transaction::BufferedWrite::UpdateEdge { edge_id, .. } => {
match tx.current.get_edge(*edge_id) {
Ok(current_edge) => {
if let Some(commit_ts) = current_edge.metadata.commit_timestamp
&& commit_ts > tx.snapshot.snapshot_timestamp
{
return Err(TransactionError::SerializationFailure {
entity: format!("{:?}", edge_id),
reason: format!(
"Version committed at {} after snapshot at {}",
commit_ts, tx.snapshot.snapshot_timestamp
),
}
.into());
}
}
Err(_) => {
return Err(TransactionError::SerializationFailure {
entity: format!("{:?}", edge_id),
reason: "Edge was deleted by another transaction".to_string(),
}
.into());
}
}
}
crate::api::transaction::BufferedWrite::DeleteNode { node_id, .. } => {
if let Ok(current_node) = tx.current.get_node(*node_id)
&& let Some(commit_ts) = current_node.metadata.commit_timestamp
&& commit_ts > tx.snapshot.snapshot_timestamp
{
return Err(TransactionError::SerializationFailure {
entity: format!("{:?}", node_id),
reason: format!(
"Version committed at {} after snapshot at {}",
commit_ts, tx.snapshot.snapshot_timestamp
),
}
.into());
}
}
crate::api::transaction::BufferedWrite::DeleteEdge { edge_id, .. } => {
if let Ok(current_edge) = tx.current.get_edge(*edge_id)
&& let Some(commit_ts) = current_edge.metadata.commit_timestamp
&& commit_ts > tx.snapshot.snapshot_timestamp
{
return Err(TransactionError::SerializationFailure {
entity: format!("{:?}", edge_id),
reason: format!(
"Version committed at {} after snapshot at {}",
commit_ts, tx.snapshot.snapshot_timestamp
),
}
.into());
}
}
_ => {}
}
}
Ok(())
}