use crate::dbs::controller::ModelParams;
use neo4rs::Graph;
use neo4rs::*;
use std::sync::Arc;
#[derive(Clone)]
pub struct Neo4J {
pub client: Option<Arc<Graph>>,
pub enable_logging: bool,
}
pub struct NodeWithRelsResult {
pub node_one: Option<Node>,
pub rel: Option<Relation>,
pub node_two: Option<Node>,
}
impl Neo4J {
pub fn new() -> Self {
Self {
client: None,
enable_logging: true,
}
}
pub async fn connect(&mut self) -> Result<Graph> {
let uri = "localhost:7687";
let user = "neo4j";
let pass = "test";
Graph::new(&uri, user, pass).await
}
fn log_query(&self, query_str: &String) {
println!("=================================");
println!("=================================");
println!("Executing Query - find_by_id");
println!("{:?}", query_str);
println!("=================================");
println!("=================================");
}
pub async fn find_node_by_id(
&self,
graph: Arc<&Graph>,
model_params: ModelParams,
id: &str,
) -> Option<Node> {
let model_name = model_params.model_name;
let model_alias = model_params.model_alias;
let graph = graph.clone();
let cypher_query_str = format_args!(
"MATCH ({model_alias}:{model_name}{{id: '{id}'}})
RETURN {model_alias}",
model_alias = model_alias,
model_name = model_name,
id = id
)
.to_string();
if self.enable_logging == true {
&self.log_query(&cypher_query_str);
}
let query_str = &cypher_query_str[..];
let mut row_stream = graph.execute(query(query_str)).await.unwrap();
let mut result_node: Option<Node> = None;
while let Ok(Some(row)) = row_stream.next().await {
result_node = Some(row.get(model_alias).unwrap());
}
result_node
}
pub async fn find_nodes_with_rels(
&self,
graph: Arc<&Graph>,
id: &str,
node_one_model_params: ModelParams,
node_two_model_params: ModelParams,
rel_model_params: ModelParams,
) -> Option<Vec<NodeWithRelsResult>> {
let node_one_model_name = node_one_model_params.model_name;
let node_one_model_alias = node_one_model_params.model_alias;
let node_two_model_name = node_two_model_params.model_name;
let node_two_model_alias = node_two_model_params.model_alias;
let rel_model_name = rel_model_params.model_name;
let rel_model_alias = rel_model_params.model_alias;
let graph = graph.clone();
let cypher_query_str = format_args!(
"MATCH ({node_one_model_alias}:{node_one_model_name}{{id: '{id}'}})-[{rel_model_alias}:{rel_model_name}]-({node_two_model_alias}:{node_two_model_name})
RETURN {node_one_model_alias}, {rel_model_alias}, {node_two_model_alias}",
node_one_model_alias = node_one_model_alias,
node_one_model_name = node_one_model_name,
node_two_model_alias = node_two_model_alias,
node_two_model_name = node_two_model_name,
rel_model_alias = rel_model_alias,
rel_model_name = rel_model_name,
id = id
)
.to_string();
if self.enable_logging == true {
&self.log_query(&cypher_query_str);
}
let query_str = &cypher_query_str[..];
let mut row_stream = graph.execute(query(query_str)).await.unwrap();
let mut results = vec![];
while let Ok(Some(row)) = row_stream.next().await {
let result_node_one: Option<Node> = Some(row.get(node_one_model_alias).unwrap());
let result_rel: Option<Relation> = Some(row.get(rel_model_alias).unwrap());
let result_node_two: Option<Node> = Some(row.get(node_two_model_alias).unwrap());
let row = NodeWithRelsResult {
node_one: result_node_one,
rel: result_rel,
node_two: result_node_two,
};
results.push(row);
}
Some(results)
}
}