use graphdblite::{Database, Value};
fn main() -> Result<(), Box<dyn std::error::Error>> {
let path = std::env::temp_dir().join("graphdblite-social-graph.db");
let _ = std::fs::remove_file(&path);
let mut db = Database::open(&path)?;
let tx = db.write_tx()?;
tx.query(
"CREATE (alice:Person {name: 'Alice', city: 'Portland'}),
(bob:Person {name: 'Bob', city: 'Seattle'}),
(carol:Person {name: 'Carol', city: 'Seattle'}),
(dave:Person {name: 'Dave', city: 'Portland'}),
(eve:Person {name: 'Eve', city: 'Boise'}),
(alice)-[:FRIEND]->(bob),
(bob)-[:FRIEND]->(carol),
(alice)-[:FRIEND]->(dave),
(dave)-[:FRIEND]->(eve),
(eve)-[:FRIEND]->(carol)",
)?;
tx.commit()?;
let tx = db.read_tx()?;
println!("== Direct friends of Alice ==");
for row in
tx.query("MATCH (a:Person {name: 'Alice'})-[:FRIEND]->(f) RETURN f.name AS friend")?
{
println!(" {}", value_str(row.get("friend")));
}
println!("\n== Friends-of-friends of Alice (2 hops, excluding Alice & direct friends) ==");
for row in tx.query(
"MATCH (a:Person {name: 'Alice'})-[:FRIEND*2]->(fof)
WHERE fof.name <> 'Alice'
AND NOT (a)-[:FRIEND]->(fof)
RETURN DISTINCT fof.name AS friend_of_friend",
)? {
println!(" {}", value_str(row.get("friend_of_friend")));
}
println!("\n== Reachable within 1..3 hops from Alice ==");
for row in tx.query(
"MATCH p = (a:Person {name: 'Alice'})-[:FRIEND*1..3]->(target)
RETURN target.name AS name, length(p) AS hops
ORDER BY hops, name",
)? {
println!(
" {} (hops={})",
value_str(row.get("name")),
value_str(row.get("hops"))
);
}
Ok(())
}
fn value_str(v: Option<&Value>) -> String {
v.map(|v| v.to_string())
.unwrap_or_else(|| "NULL".to_string())
}