Skip to content
This repository has been archived by the owner on Oct 25, 2024. It is now read-only.

Commit

Permalink
Begin to integrate existing argument parser into new implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
deekerno committed Nov 7, 2023
1 parent e3be868 commit f1e24fc
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 19 deletions.
43 changes: 26 additions & 17 deletions packages/fuel-indexer-graphql/src/arguments.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use super::graphql::GraphqlError;
use fuel_indexer_database::DbType;
use fuel_indexer_schema::db::tables::IndexerSchema;
use fuel_indexer_lib::graphql::ParsedGraphQLSchema;

use async_graphql_value::{indexmap::IndexMap, Name, Value};
use std::fmt;
Expand All @@ -12,6 +12,7 @@ pub struct QueryParams {
pub sorts: Vec<Sort>,
pub offset: Option<u64>,
pub limit: Option<u64>,
pub cursor: Option<String>,
}

impl QueryParams {
Expand All @@ -36,6 +37,7 @@ impl QueryParams {
}),
ParamType::Offset(n) => self.offset = Some(n),
ParamType::Limit(n) => self.limit = Some(n),
ParamType::Cursor(s) => self.cursor = Some(s),
}
}
}
Expand Down Expand Up @@ -102,6 +104,7 @@ pub enum ParamType {
Sort(String, SortOrder),
Offset(u64),
Limit(u64),
Cursor(String),
}

#[derive(Debug, Clone, PartialEq, Eq)]
Expand Down Expand Up @@ -368,15 +371,15 @@ impl FilterType {
}
}

/// Parse an argument key-value pair into a `Filter`.
/// Parse an argument key-value pair into a `ParamType`.
///
/// `parse_arguments` is the entry point for parsing all API query arguments.
/// Any new top-level operators should first be added here.
pub fn parse_argument_into_param(
entity_type: Option<&String>,
arg: &str,
value: Value,
schema: &IndexerSchema,
schema: &ParsedGraphQLSchema,
) -> Result<ParamType, GraphqlError> {
match arg {
"filter" => {
Expand All @@ -399,11 +402,7 @@ pub fn parse_argument_into_param(
"order" => {
if let Value::Object(obj) = value {
if let Some((field, sort_order)) = obj.into_iter().next() {
if schema
.parsed()
.graphql_type(entity_type, field.as_str())
.is_some()
{
if schema.graphql_type(entity_type, field.as_str()).is_some() {
if let Value::Enum(sort_order) = sort_order {
match sort_order.as_str() {
"asc" => {
Expand Down Expand Up @@ -458,6 +457,20 @@ pub fn parse_argument_into_param(
Err(GraphqlError::UnsupportedValueType(value.to_string()))
}
}
"before" => {
if let Value::String(s) = value {
Ok(ParamType::Cursor(s))
} else {
Err(GraphqlError::UnsupportedValueType(value.to_string()))
}
}
"after" => {
if let Value::String(s) = value {
Ok(ParamType::Cursor(s))
} else {
Err(GraphqlError::UnsupportedValueType(value.to_string()))
}
}
_ => {
if let Some(entity) = entity_type {
Err(GraphqlError::UnrecognizedArgument(
Expand All @@ -481,7 +494,7 @@ pub fn parse_argument_into_param(
fn parse_filter_object(
obj: IndexMap<Name, Value>,
entity_type: Option<&String>,
schema: &IndexerSchema,
schema: &ParsedGraphQLSchema,
prior_filter: &mut Option<FilterType>,
) -> Result<FilterType, GraphqlError> {
let mut iter = obj.into_iter();
Expand Down Expand Up @@ -510,7 +523,7 @@ fn parse_arg_pred_pair(
key: &str,
predicate: Value,
entity_type: Option<&String>,
schema: &IndexerSchema,
schema: &ParsedGraphQLSchema,
prior_filter: &mut Option<FilterType>,
top_level_arg_value_iter: &mut impl Iterator<Item = (Name, Value)>,
) -> Result<FilterType, GraphqlError> {
Expand All @@ -520,11 +533,7 @@ fn parse_arg_pred_pair(
let mut column_list = vec![];
for element in elements {
if let Value::Enum(column) = element {
if schema
.parsed()
.graphql_type(entity_type, column.as_str())
.is_some()
{
if schema.graphql_type(entity_type, column.as_str()).is_some() {
column_list.push(column.to_string())
} else if let Some(entity) = entity_type {
return Err(GraphqlError::UnrecognizedField(
Expand Down Expand Up @@ -570,7 +579,7 @@ fn parse_arg_pred_pair(
}
}
other => {
if schema.parsed().graphql_type(entity_type, other).is_some() {
if schema.graphql_type(entity_type, other).is_some() {
if let Value::Object(inner_obj) = predicate {
for (key, predicate) in inner_obj.iter() {
match key.as_str() {
Expand Down Expand Up @@ -668,7 +677,7 @@ fn parse_binary_logical_operator(
key: &str,
predicate: Value,
entity_type: Option<&String>,
schema: &IndexerSchema,
schema: &ParsedGraphQLSchema,
top_level_arg_value_iter: &mut impl Iterator<Item = (Name, Value)>,
prior_filter: &mut Option<FilterType>,
) -> Result<FilterType, GraphqlError> {
Expand Down
2 changes: 1 addition & 1 deletion packages/fuel-indexer-graphql/src/graphql.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ impl Selections {
Some(subfield_type),
&arg.to_string(),
value.node.clone(),
schema,
schema.parsed(),
)
})
.collect::<Result<Vec<ParamType>, GraphqlError>>()?;
Expand Down
1 change: 1 addition & 0 deletions packages/fuel-indexer-graphql/src/queries.rs
Original file line number Diff line number Diff line change
Expand Up @@ -466,6 +466,7 @@ mod tests {
sorts: vec![],
offset: None,
limit: None,
cursor: None,
},
alias: None,
};
Expand Down
27 changes: 26 additions & 1 deletion packages/fuel-indexer-graphql/src/query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,10 @@ use fuel_indexer_database::DbType;
use fuel_indexer_lib::graphql::{parser::InternalType, ParsedGraphQLSchema};
use petgraph::graph::{Graph, NodeIndex};

use crate::graphql::{GraphqlError, GraphqlResult};
use crate::{
arguments::{parse_argument_into_param, ParamType},
graphql::{GraphqlError, GraphqlResult},
};

/// Contains information about a successfully-parsed user operation.
#[derive(Debug)]
Expand Down Expand Up @@ -210,6 +213,7 @@ pub enum SelectionNode {
alias: Option<Positioned<Name>>,
fields: Vec<SelectionNode>,
is_part_of_list: bool,
arguments: Vec<ParamType>,
},
List {
name: Name,
Expand All @@ -220,6 +224,7 @@ pub enum SelectionNode {
name: Name,
alias: Option<Positioned<Name>>,
fields: Vec<SelectionNode>,
arguments: Vec<ParamType>,
},
PageInfo {
name: Name,
Expand All @@ -232,6 +237,7 @@ pub enum SelectionNode {
alias: Option<Positioned<Name>>,
entity: String,
fields: Vec<SelectionNode>,
arguments: Vec<ParamType>,
},
Edge {
name: Name,
Expand Down Expand Up @@ -288,6 +294,7 @@ impl SelectionNode {
fields,
parent_entity,
is_part_of_list,
arguments: _,
} => {
if let Some(fk_map) = schema
.foreign_key_mappings()
Expand Down Expand Up @@ -375,6 +382,7 @@ impl SelectionNode {
alias,
entity: _,
fields,
arguments: _,
} => {
// Connection types require a special process for resolving
// queries. Instead of calling the .prepare() method on the
Expand Down Expand Up @@ -457,6 +465,20 @@ fn parse_selections(
let parsed_selections = selections.iter().try_fold(vec![], |mut v, selection| {
Ok(match &selection.node {
Selection::Field(f) => {
let field_type = schema.graphql_type(parent_obj, &f.node.name.node);
let arguments = f
.node
.arguments
.iter()
.map(|(arg, value)| {
parse_argument_into_param(
field_type,
&arg.to_string(),
value.node.clone(),
schema,
)
})
.collect::<GraphqlResult<Vec<ParamType>>>()?;
if let Some(parent) = parent_obj {
let has_no_subselections = f.node.selection_set.node.items.is_empty();
let (is_list_field, internal_type) = if let Some(parent) = parent_obj
Expand Down Expand Up @@ -532,6 +554,7 @@ fn parse_selections(
alias: f.node.alias.clone(),
entity,
fields,
arguments,
},
InternalType::Edge => {
let (cursor, fields) = if let Some(idx) =
Expand Down Expand Up @@ -581,6 +604,7 @@ fn parse_selections(
fields,
parent_entity: parent.to_string(),
is_part_of_list: is_list_field,
arguments,
}
};

Expand All @@ -607,6 +631,7 @@ fn parse_selections(
name: f.node.name.node.clone(),
alias: f.node.alias.clone(),
fields,
arguments,
});
v
}
Expand Down

0 comments on commit f1e24fc

Please sign in to comment.