use clap::Parser;
use neo4j_cli::{Cli, Commands};
use neo4rs::{query, Graph};
use rustyline::DefaultEditor;
use std::error::Error;
use std::fmt;
use std::sync::Arc;
static mut GLOBAL_GRAPH: Option<Arc<Graph>> = None;
#[tokio::main]
async fn main() {
let args = Cli::parse();
match &args.command {
Commands::Connect(obj) => {
if let Err(err) = connect(&obj.uri, &obj.username, &obj.password).await {
println!("Failed to connect to Neo4j database: {:?}", err);
return;
}
}
}
}
#[derive(Debug)]
enum CustomError {
Neo4rsError(neo4rs::Error),
ReadlineError(rustyline::error::ReadlineError),
}
impl Error for CustomError {
fn source(&self) -> Option<&(dyn Error + 'static)> {
match self {
CustomError::Neo4rsError(err) => Some(err),
CustomError::ReadlineError(err) => Some(err),
}
}
}
impl fmt::Display for CustomError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
CustomError::Neo4rsError(err) => write!(f, "Neo4rs Error: {}", err),
CustomError::ReadlineError(err) => write!(f, "Readline Error: {}", err),
}
}
}
async fn connect(
uri: &str,
username: &str,
password: &str,
) -> Result<(), Box<dyn std::error::Error>> {
let graph = Arc::new(Graph::new(uri, username, password).await?);
unsafe {
GLOBAL_GRAPH = Some(graph);
}
println!("Connected to Neo4j database at: {}", uri);
let mut rl = DefaultEditor::new()?;
loop {
let readline = rl.readline(">> ")?;
println!("{}", readline);
execute_query(&readline).await;
}
}
async fn execute_query(line: &String) {
unsafe {
if let Some(graph) = &GLOBAL_GRAPH {
let mut result = graph.execute(query(line)).await.unwrap();
while let Some(row) = result.next().await.unwrap() {
println!("{:?}", row);
}
} else {
println!("You need to connect to the database first.");
}
}
}
async fn test_query() {
unsafe {
if let Some(graph) = &GLOBAL_GRAPH {
let mut result = graph
.execute(
query("MATCH (a:AS {asn: $asn})-[:NAME]-(b:Name) RETURN a.asn as asn, b.name AS name")
.param("asn", 2497),
)
.await
.unwrap();
while let Some(row) = result.next().await.unwrap() {
println!("{:?}", row);
}
} else {
println!("You need to connect to the database first.");
}
}
}