Skip to content

Commit

Permalink
feat(dvmql): add logging
Browse files Browse the repository at this point in the history
  • Loading branch information
sotirangelo committed May 8, 2024
1 parent 2b25a13 commit a9ccd4e
Show file tree
Hide file tree
Showing 8 changed files with 142 additions and 30 deletions.
87 changes: 86 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,5 @@ neo4rs = "0.7.1"
tokio = { version = "1.35.1", features = ["full"] }
async-recursion = "1.0.5"
tokio-postgres = "0.7.10"
log = "0.4.20"
env_logger = "0.10.2"
13 changes: 11 additions & 2 deletions src/dvmql/datasources.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,17 @@
//! This module containts deserialization logic for the datasources XML file.

use anyhow::Result;
use log::{debug, info, trace};
use serde::Deserialize;
use std::collections::HashMap;

use super::helpers::read_xml_file;

/// Helper function for loading and deserializing the datasources XML file
pub fn load_datasources_xml(datasources_path: String) -> Result<HashMap<String, Datasource>> {
let init_datasources: DeserializedDatasources = read_xml_file(datasources_path)?;
info!("Loading datasources from {}", datasources_path);
let init_datasources: DeserializedDatasources = read_xml_file(&datasources_path)?;
debug!("Deserialized datasources from XML {}", datasources_path);
let res: HashMap<String, Datasource> = init_datasources
.datasource
.iter()
Expand All @@ -23,9 +26,15 @@ pub fn load_datasources_xml(datasources_path: String) -> Result<HashMap<String,
// TODO: Handle error
&_ => panic!("Incorrect datasource type given: {}", init_ds.ds_type),
};
trace!(
"Collecting {} datasource: {}",
init_ds.ds_type.to_uppercase(),
init_ds.name
);
(init_ds.name.clone(), ds)
})
.collect();
debug!("Built collection of datasources from datasources XML");
Ok(res)
}

Expand Down Expand Up @@ -306,7 +315,7 @@ mod tests {
#[test]
fn test_loading_initial_datasource_structs() {
let path = get_test_file_path();
let datasources: DeserializedDatasources = read_xml_file(path).unwrap();
let datasources: DeserializedDatasources = read_xml_file(&path).unwrap();
assert_eq!(datasources, get_init_datasources());
}

Expand Down
4 changes: 2 additions & 2 deletions src/dvmql/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ use serde::de::DeserializeOwned;
use std::{fs::File, io::BufReader};

/// Helper function for reading an XML file and deserializing it into a struct.
pub fn read_xml_file<T: DeserializeOwned>(xml_file_path: String) -> Result<T> {
let file = File::open(&xml_file_path)
pub fn read_xml_file<T: DeserializeOwned>(xml_file_path: &str) -> Result<T> {
let file = File::open(xml_file_path)
.with_context(|| format!("Failed to open file: {}", &xml_file_path))?;
let reader = BufReader::new(file);
from_reader(reader).with_context(|| format!("Failed to parse XML file: {}", &xml_file_path))
Expand Down
2 changes: 1 addition & 1 deletion src/dvmql/query/deserialization.rs
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,6 @@ mod tests {
path.push("test_data/example_query.xml");
let path = path.to_str().unwrap().to_string();
let expected_query = get_expected_query();
assert_eq!(read_xml_file::<Query>(path).unwrap(), expected_query)
assert_eq!(read_xml_file::<Query>(&path).unwrap(), expected_query)
}
}
6 changes: 5 additions & 1 deletion src/dvmql/query/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,17 @@ mod deserialization;
pub mod tree;

use anyhow::Result;
use log::{debug, info};

use self::{deserialization::Query, tree::TreeNode};
use crate::dvmql::helpers::read_xml_file;

/// Helper function for loading a query XML file and building the tree structure.
pub fn load_query_xml(query_path: String) -> Result<TreeNode> {
let query: Query = read_xml_file(query_path)?;
info!("Loading query from {}", query_path);
let query: Query = read_xml_file(&query_path)?;
debug!("Deserialized query from XML {}", query_path);
let tree = tree::build_tree(query)?;
debug!("Built tree from query XML");
Ok(tree)
}
6 changes: 4 additions & 2 deletions src/dvmql/query/tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@
//! This module contains the logic for building the tree structure defined in a DVMQL query.

use anyhow::{Context, Result};
use log::trace;
use std::collections::HashMap;

use crate::{dvmql::query::deserialization::DeserializedNode, transform::Transformation};
use super::deserialization::Query;
use crate::{dvmql::query::deserialization::DeserializedNode, transform::Transformation};

/// Node of the tree structure defined in a DVMQL query.
pub struct TreeNode {
Expand Down Expand Up @@ -84,7 +85,8 @@ fn build_node(
child_name.clone()
)
})?;
build_node(child, nodes_map)
trace!("Building tree node {}: {}", child.name, child.label);
build_node(child, nodes_map)
})
.collect::<Result<Vec<TreeNode>>>()?;
tree_node.children = children;
Expand Down
52 changes: 31 additions & 21 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@ mod transform;

use std::collections::HashMap;

use anyhow::Result;
use anyhow::{Context, Result};
use async_recursion::async_recursion;

use clap::Parser;

use dvmql::{
datasources::{self, Datasource},
query::tree::TreeNode,
};
use dvmql::{datasources, query::tree::TreeNode};
use env_logger::Builder;
use load::Datasource;
use log::{trace, LevelFilter};
use neo4rs::{query, Graph};

use crate::{dvmql::query::load_query_xml, load::edges::Edge};
Expand All @@ -27,6 +27,8 @@ struct Args {
output: String,
#[arg(short, long, default_value_t = String::from("ALL"))]
mode: String,
#[arg(short, long, action = clap::ArgAction::Count)]
debug: u8,
}

const QUERY: &str = "MATCH (a:attribute{name: $nodeA})-[r:has]->(b:attribute{name: $nodeB}) RETURN r.datasource as datasource, r.query as query, r.key as key, r.value as value";
Expand All @@ -39,10 +41,7 @@ async fn dfs(
) -> Result<()> {
for child in &node.children {
dfs(child, graph, datasources).await?;
}

println!("Evaluating {}", &node.label);
for child in &node.children {
let mut result = graph
.execute(
query(QUERY)
Expand All @@ -51,31 +50,42 @@ async fn dfs(
)
.await?;
while let Some(r) = result.next().await? {
let datasource: String = r.to::<Edge>().unwrap().datasource_name;
let key: u32 = r.to::<Edge>().unwrap().key_pos;
let value: u32 = r.to::<Edge>().unwrap().value_pos;
println!("Datasource: {}, Key: {}, Value: {}", datasource, key, value);
datasources.get(&datasource).unwrap_or_else(|| {
panic!("Datasource {} not found in datasources list", &datasource)
});
let datasource: String = r.to::<Edge>()?.datasource_name;
let key: u32 = r.to::<Edge>()?.key_pos;
let value: u32 = r.to::<Edge>()?.value_pos;
let dt = datasources.get(&datasource).with_context(|| {
format!("Datasource {} not found in datasources list", &datasource)
})?;
trace!("Edge {} => {}", &child.label, &node.label);
}
println!("Finished with child {}", &child.label);
}
Ok(())
}

#[tokio::main]
async fn main() -> Result<()> {
// Parse CLI arguments
let args = Args::parse();
println!("{:?}", args);

let _neo4j_graph = Graph::new("bolt://localhost:7687", "neo4j", "12345678").await?;
assert!(_neo4j_graph.run(query("RETURN 1")).await.is_ok());
// Initialize logger
let log_level = match args.debug {
1 => LevelFilter::Info,
2 => LevelFilter::Debug,
3 => LevelFilter::Trace,
_ => LevelFilter::Error,
};
Builder::new().filter_level(log_level).init();

// Initialize Neo4j graph
let neo4j = Graph::new("bolt://localhost:7687", "neo4j", "12345678").await?;
assert!(neo4j.run(query("RETURN 1")).await.is_ok());

// Load query & datasources
let tree = load_query_xml(args.query_path)?;
let _datasources = datasources::load_datasources_xml(args.datasources_path)?;
let datasources = datasources::load_datasources_xml(args.datasources_path)?;

dfs(&tree, &_neo4j_graph, &_datasources).await?;
// Execute query
dfs(&tree, &neo4j, &datasources).await?;

Ok(())
}

0 comments on commit a9ccd4e

Please sign in to comment.