Commit fa1692e6 authored by Alp Deniz Ogut's avatar Alp Deniz Ogut
Browse files

Re-iterate & refactor. Add test, pass tests

parent e8aabdb1
Showing with 68 additions and 35 deletions
+68 -35
......@@ -75,7 +75,12 @@ pub fn parse_graphql_query(query_string: &str) -> Result<QueryASTNode> {
if let Definition::Operation(OperationDefinition::Query(top_level_query)) = def.to_owned() {
let selection_set = top_level_query.selection_set;
parse_query_recursive(selection_set)
let mut query = parse_query_recursive(selection_set)?;
// only pick the first edge (the root query) and set its type
if let Some((item_type, node)) = query.edges.iter_mut().next() {
node.item_type = Some(item_type.to_string());
}
Ok(query)
} else {
panic!("Selectionsets/Mutations/Subscriptions are not supported");
}
......@@ -408,15 +413,16 @@ pub mod tests {
";
let query_ast = parse_graphql_query(test_query)?;
let root_ast = query_ast.edges.values().next().unwrap();
assert_eq!(query_ast.item_type, Some("Message".to_owned()));
assert_eq!(query_ast.properties, ["id", "content"]);
assert_eq!(query_ast.edges.len(), 1);
assert_eq!(root_ast.item_type, Some("Message".to_owned()));
assert_eq!(root_ast.properties, ["id", "content"]);
assert_eq!(root_ast.edges.len(), 1);
let (edge_name, edge_ast) = query_ast.edges.iter().next().unwrap();
let (edge_name, edge_ast) = root_ast.edges.iter().next().unwrap();
assert_eq!(edge_name, "author");
assert_eq!(edge_ast.properties, ["id"]);
println!("{:?}", query_ast.arguments);
println!("{:?}", root_ast.arguments);
Ok(())
}
......@@ -436,15 +442,16 @@ pub mod tests {
";
let query_ast = parse_graphql_query(test_query)?;
let root_ast = query_ast.edges.values().next().unwrap();
assert_eq!(query_ast.item_type, Some("Message".to_owned()));
assert_eq!(query_ast.properties, ["id", "content"]);
assert_eq!(query_ast.edges.len(), 1);
assert_eq!(root_ast.item_type, Some("Message".to_owned()));
assert_eq!(root_ast.properties, ["id", "content"]);
assert_eq!(root_ast.edges.len(), 1);
let (edge_name, edge_ast) = query_ast.edges.iter().next().unwrap();
let (edge_name, edge_ast) = root_ast.edges.iter().next().unwrap();
assert_eq!(edge_name, "author");
assert_eq!(edge_ast.properties, ["id"]);
println!("{:?}", query_ast.arguments);
println!("{:?}", root_ast.arguments);
Ok(())
}
......
......@@ -534,26 +534,42 @@ fn gql_search_recursive(
}
pub fn graphql(tx: &Tx, schema: &Schema, query: String) -> Result<HashMap<String, Value>> {
let mut query_ast: QueryASTNode = graphql_utils::parse_graphql_query(&query).unwrap();
let query_ast: QueryASTNode = graphql_utils::parse_graphql_query(&query).unwrap();
let query_edges = query_ast.edges.values().collect::<Vec<&QueryASTNode>>();
// Allow only and only one query per request
if query_edges.len() != 1 {
return Err(Error {
code: StatusCode::BAD_REQUEST,
msg: format!(
"Strictly one root query is allowed. Provided {}",
query_edges.len()
),
});
}
let search_root_ast = query_edges.first().unwrap();
let search_result = gql_search_recursive(tx, search_root_ast, schema, None, 0)?;
let mut result = HashMap::new();
for (item_type, node) in query_ast.edges.iter_mut() {
node.item_type = Some(item_type.to_string());
let search_result = gql_search_recursive(tx, node, schema, None, 0)?;
result.insert("data".to_owned(), serde_json::json!(search_result));
for meta in query_ast.properties {
let data = match meta.as_str() {
"count" => serde_json::json!(search_result.len()),
"total" => {
let mut query = GQLSearchArgs::default();
query._type = node.item_type.to_owned();
query.filters = node.arguments.filters.to_owned();
serde_json::json!(database_api::get_total_count(tx, &query)?)
}
_ => panic!("Invalid metadata request"),
};
result.insert(meta, data);
}
break; // do not allow multiple queries
result.insert("data".to_owned(), serde_json::json!(search_result));
for meta in query_ast.properties {
let data = match meta.as_str() {
"count" => serde_json::json!(search_result.len()),
"total" => {
let query = GQLSearchArgs {
_type: search_root_ast.item_type.to_owned(),
filters: search_root_ast.arguments.filters.to_owned(),
..Default::default()
};
serde_json::json!(database_api::get_total_count(tx, &query)?)
}
_ => {
return Err(Error {
code: StatusCode::BAD_REQUEST,
msg: format!("Invalid metadata request: {}", meta),
})
}
};
result.insert(meta, data);
}
Ok(result)
}
......@@ -897,6 +913,8 @@ pub mod tests {
// assert_eq!(data.len(), 2000);
let items_with_friends = data
.as_array()
.unwrap()
.iter()
.filter_map(|x| x.get("friend1"))
.filter(|x| !x.as_array().unwrap().is_empty());
......@@ -918,7 +936,7 @@ pub mod tests {
assert!(friend_age > 0, "Cannot get edge item property: age");
}
// test limit and offset
// test limit, offset and meta (count, total)
let query = "
query {
Person1 (limit: 10, offset: 5) {
......@@ -927,14 +945,20 @@ pub mod tests {
id
}
}
count
total
}"
.to_owned();
// print!("{:}", serde_json::to_string_pretty(&json!(data)).unwrap());
let res = graphql(&tx, &schema, query);
let data = res.unwrap();
let data = data.get("data").unwrap();
let res = graphql(&tx, &schema, query).unwrap();
let data = res.get("data").unwrap().as_array().unwrap();
assert_eq!(data.len(), 10);
let count = res.get("count").unwrap().as_i64().unwrap();
assert_eq!(count, 10);
let total = res.get("total").unwrap().as_i64().unwrap();
assert_eq!(total, 1000);
}
#[test]
......@@ -975,6 +999,8 @@ pub mod tests {
// assert_eq!(data.len(), 2000);
let items_with_friends = data
.as_array()
.unwrap()
.iter()
.filter_map(|x| x.get("friend1"))
.filter(|x| !x.as_array().unwrap().is_empty());
......@@ -994,7 +1020,7 @@ pub mod tests {
.to_owned();
let res = graphql(&tx, &schema, query);
let data = res.unwrap();
let data = data.get("data").unwrap();
let data = data.get("data").unwrap().as_array().unwrap();
assert_eq!(data.len(), 999);
}
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment