use rocksgraph::{Graph, StoreError, TraversalBuilder, Value};
fn main() -> Result<(), Box<dyn std::error::Error>> {
let temp_dir = tempfile::tempdir()?;
let db_path = temp_dir.path();
println!("Initializing Graph Database at: {:?}", db_path);
let graph = Graph::open(db_path)?;
println!("\n--- Phase 1: Writing Initial Graph Data ---");
let mut tx = graph.begin();
tx.g().addV("person").property("id", 1i64).property("name", "marko").property("age", 29i32).next()?;
tx.g().addV("person").property("id", 2i64).property("name", "vadas").property("age", 27i32).next()?;
tx.g().addE("knows").from(1).to(2).property("weight", 0.5f64).next()?;
tx.commit()?;
println!("Graph data successfully committed!");
println!("\n--- Phase 2: Querying the Graph (Read-Only Session) ---");
let mut snap = graph.read();
let marko_age = snap.g().V([1]).values(["age"]).next()?;
println!("Marko's age: {:?}", marko_age);
let friends = snap.g().V([1]).out(["knows"]).values(["name"]).to_list()?;
println!("People Marko knows: {:?}", friends);
println!("\n--- Phase 3: Writing with OCC Conflict Retry Loop ---");
let mut retries = 0;
loop {
let mut tx = graph.begin();
let current_age = tx
.g()
.V([1])
.values(["age"])
.next()?
.and_then(|v| match v {
Value::Int32(age) => Some(age),
_ => None,
})
.unwrap_or(29);
tx.g().V([1]).property("age", current_age + 1).next()?;
match tx.commit() {
Ok(_) => {
println!("Successfully updated Marko's age to {} after {} retries.", current_age + 1, retries);
break;
}
Err(StoreError::Conflict) => {
retries += 1;
println!("OCC Conflict detected! Retrying transaction (attempt {})...", retries);
continue;
}
Err(e) => {
return Err(Box::new(e));
}
}
}
Ok(())
}