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

Commit

Permalink
Remove some of the format!() calls
Browse files Browse the repository at this point in the history
  • Loading branch information
deekerno committed Nov 9, 2023
1 parent 646d02b commit 0db936f
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 25 deletions.
4 changes: 2 additions & 2 deletions packages/fuel-indexer-graphql/src/dynamic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ pub async fn execute_query(
)?;

let query = parsed.prepare(schema.parsed(), &pool.database_type())?;
vec![query]
vec![query.as_sql()]
}
DocumentOperations::Multiple(op_defs) => {
let mut v = vec![];
Expand All @@ -149,7 +149,7 @@ pub async fn execute_query(
Some(name.to_string()),
)?;
let s = parsed.prepare(schema.parsed(), &pool.database_type())?;
v.push(s);
v.push(s.as_sql());
}

v
Expand Down
98 changes: 75 additions & 23 deletions packages/fuel-indexer-graphql/src/query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use async_graphql_parser::{
};
use async_graphql_value::Name;
use fuel_indexer_database::DbType;
use fuel_indexer_database_types::SqlFragment;
use fuel_indexer_lib::graphql::{parser::InternalType, ParsedGraphQLSchema};
use petgraph::graph::{Graph, NodeIndex};

Expand All @@ -34,6 +35,29 @@ pub struct DependencyGraph {
pub graph: Graph<String, (String, String)>,
}

#[allow(unused)]
pub struct Join {
pub child_table: String,
pub parent_table: String,
pub referring_field: String,
pub fk_field: String,
// TODO: Allow for different join types
pub join_type: String,
}

impl SqlFragment for Join {
fn create(&self) -> String {
format!(
"INNER JOIN {} ON {}.{} = {}.{}",
self.child_table,
self.parent_table,
self.referring_field,
self.child_table,
self.fk_field
)
}
}

impl DependencyGraph {
/// Add a new node to dependency graph.
fn add_node(&mut self, table: String) -> NodeIndex {
Expand All @@ -59,7 +83,7 @@ impl DependencyGraph {
}

/// Returns database joins in topologically sorted order.
fn get_sorted_joins(&self) -> GraphqlResult<Vec<String>> {
fn get_sorted_joins(&self) -> GraphqlResult<Vec<Join>> {
let toposorted_nodes =
if let Ok(sorted) = petgraph::algo::toposort(&self.graph, None) {
sorted
Expand All @@ -69,7 +93,7 @@ impl DependencyGraph {
));
};

let mut joins: Vec<String> = vec![];
let mut joins: Vec<Join> = vec![];
let mut seen = vec![false; self.graph.node_count()];

let mut stack = VecDeque::new();
Expand All @@ -95,15 +119,13 @@ impl DependencyGraph {
self.graph.node_weight(parent_node),
self.graph.node_weight(child_node),
) {
let join = format!(
"INNER JOIN {} ON {}.{} = {}.{}",
child_table,
parent_table,
referring_field,
child_table,
fk_field
);
joins.push(join);
joins.push(Join {
child_table: child_table.to_owned(),
parent_table: parent_table.to_owned(),
referring_field: referring_field.to_owned(),
fk_field: fk_field.to_owned(),
join_type: "INNER".to_string(),
});
}

stack.push_front(child_node);
Expand All @@ -117,6 +139,39 @@ impl DependencyGraph {
}
}

pub struct PreparedOperation {
pub selections: Vec<String>,
pub fully_qualified_namespace: String,
pub root_object_name: Name,
pub joins: Vec<Join>,
pub query_parameters: QueryParams,
pub db_type: DbType,
}

impl PreparedOperation {
pub fn as_sql(&self) -> String {
match self.db_type {
DbType::Postgres => {
format!(
"SELECT json_build_object({}) FROM {}.{} {} {} {}",
self.selections.join(""),
self.fully_qualified_namespace,
self.root_object_name,
self.joins
.iter()
.map(|j| j.create())
.collect::<Vec<String>>()
.join(" "),
self.query_parameters
.get_filtering_expression(&DbType::Postgres),
self.query_parameters
.get_ordering_modififer(&DbType::Postgres)
)
}
}
}
}

impl ParsedOperation {
/// Creates a `ParsedOperation` from a user's operation.
pub fn generate(
Expand Down Expand Up @@ -152,7 +207,7 @@ impl ParsedOperation {
&self,
schema: &ParsedGraphQLSchema,
db_type: &DbType,
) -> GraphqlResult<String> {
) -> GraphqlResult<PreparedOperation> {
match self.ty {
OperationType::Query => match db_type {
DbType::Postgres => match &self.selections[0] {
Expand All @@ -176,17 +231,14 @@ impl ParsedOperation {
}
}

let joins = dep_graph.get_sorted_joins()?;

Ok(format!(
"SELECT json_build_object({}) FROM {}.{} {} {} {}",
selections.join(""),
schema.fully_qualified_namespace(),
name,
joins.join(" "),
query_parameters.get_filtering_expression(db_type),
query_parameters.get_ordering_modififer(db_type)
))
Ok(PreparedOperation {
selections,
fully_qualified_namespace: schema.fully_qualified_namespace(),
root_object_name: name.to_owned(),
joins: dep_graph.get_sorted_joins()?,
query_parameters,
db_type: db_type.to_owned(),
})
}
_ => Err(GraphqlError::QueryError(
"Query must begin with an object".to_string(),
Expand Down

0 comments on commit 0db936f

Please sign in to comment.