Skip to content
GitLab
Explore
Projects
Groups
Snippets
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
David Kosztka
Pod
Commits
fa1692e6
Commit
fa1692e6
authored
2 years ago
by
Alp Deniz Ogut
Browse files
Options
Download
Email Patches
Plain Diff
Re-iterate & refactor. Add test, pass tests
parent
e8aabdb1
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
src/graphql_utils.rs
+18
-11
src/graphql_utils.rs
src/internal_api.rs
+50
-24
src/internal_api.rs
with
68 additions
and
35 deletions
+68
-35
src/graphql_utils.rs
+
18
-
11
View file @
fa1692e6
...
...
@@ -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
(())
}
...
...
This diff is collapsed.
Click to expand it.
src/internal_api.rs
+
50
-
24
View file @
fa1692e6
...
...
@@ -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
);
}
...
...
This diff is collapsed.
Click to expand it.
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment
Menu
Explore
Projects
Groups
Snippets