Skip to content

Commit 99b4178

Browse files
committed
feat(gb-9065): try to reduce the amount of unused types in intro
1 parent 82a898b commit 99b4178

File tree

14 files changed

+17040
-116009
lines changed

14 files changed

+17040
-116009
lines changed

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

cli/postgres/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "grafbase-postgres"
3-
version = "0.3.3"
3+
version = "0.3.4"
44
edition = "2024"
55
license = "Apache-2.0"
66

crates/postgres-introspection/src/render.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,5 +55,7 @@ pub fn to_sdl(database_definition: DatabaseDefinition, config: &Config) -> Strin
5555
mutation::render(&database_definition, config, prefix, &mut rendered);
5656
}
5757

58+
rendered.remove_unused_types();
59+
5860
rendered.to_string()
5961
}

crates/postgres-introspection/src/render/ast/directive.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -55,10 +55,10 @@ impl fmt::Display for ArgumentValue<'_> {
5555
}
5656

5757
pub struct Argument<'a> {
58-
name: Cow<'a, str>,
59-
value: ArgumentValue<'a>,
60-
description: Option<Cow<'a, str>>,
61-
directives: Vec<Directive<'a>>,
58+
pub(super) name: Cow<'a, str>,
59+
pub(super) value: ArgumentValue<'a>,
60+
pub(super) description: Option<Cow<'a, str>>,
61+
pub(super) directives: Vec<Directive<'a>>,
6262
}
6363

6464
impl<'a> Argument<'a> {

crates/postgres-introspection/src/render/ast/enum.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@ use std::{borrow::Cow, fmt};
33
use super::directive::Directive;
44

55
pub struct Enum<'a> {
6-
name: &'a str,
7-
directives: Vec<Directive<'a>>,
8-
variants: Vec<EnumVariant<'a>>,
9-
description: Option<Cow<'a, str>>,
6+
pub(super) name: &'a str,
7+
pub(super) directives: Vec<Directive<'a>>,
8+
pub(super) variants: Vec<EnumVariant<'a>>,
9+
pub(super) description: Option<Cow<'a, str>>,
1010
}
1111

1212
impl<'a> Enum<'a> {

crates/postgres-introspection/src/render/ast/field.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,12 @@ use indenter::indented;
66
use super::directive::{Argument, Directive};
77

88
pub struct Field<'a> {
9-
name: Cow<'a, str>,
10-
r#type: Cow<'a, str>,
11-
directives: Vec<Directive<'a>>,
12-
arguments: Vec<Argument<'a>>,
13-
description: Option<Cow<'a, str>>,
14-
render_multiline: bool,
9+
pub(super) name: Cow<'a, str>,
10+
pub(super) r#type: Cow<'a, str>,
11+
pub(super) directives: Vec<Directive<'a>>,
12+
pub(super) arguments: Vec<Argument<'a>>,
13+
pub(super) description: Option<Cow<'a, str>>,
14+
pub(super) render_multiline: bool,
1515
}
1616

1717
impl<'a> Field<'a> {

crates/postgres-introspection/src/render/ast/input.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,10 @@ use std::{
66
use super::{directive::Directive, field::Field};
77

88
pub struct InputType<'a> {
9-
name: Cow<'a, str>,
10-
directives: Vec<Directive<'a>>,
11-
fields: Vec<Field<'a>>,
12-
description: Option<Cow<'a, str>>,
9+
pub(super) name: Cow<'a, str>,
10+
pub(super) directives: Vec<Directive<'a>>,
11+
pub(super) fields: Vec<Field<'a>>,
12+
pub(super) description: Option<Cow<'a, str>>,
1313
}
1414

1515
impl<'a> InputType<'a> {

crates/postgres-introspection/src/render/ast/scalar.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ use std::borrow::Cow;
22
use std::fmt;
33

44
pub struct Scalar<'a> {
5-
name: &'a str,
6-
description: Option<Cow<'a, str>>,
5+
pub(super) name: &'a str,
6+
pub(super) description: Option<Cow<'a, str>>,
77
}
88

99
impl<'a> Scalar<'a> {

crates/postgres-introspection/src/render/ast/schema.rs

Lines changed: 95 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
1-
use std::fmt;
1+
use std::{cmp::Ordering, collections::HashSet, fmt};
22

3-
use super::{directive::Directive, r#enum::Enum, input::InputType, scalar::Scalar, r#type::Type};
3+
use super::{
4+
directive::{ArgumentValue, Directive},
5+
r#enum::Enum,
6+
input::InputType,
7+
scalar::Scalar,
8+
r#type::Type,
9+
};
410

511
#[derive(Default)]
612
pub struct Schema<'a> {
@@ -35,6 +41,93 @@ impl<'a> Schema<'a> {
3541
pub fn push_scalar(&mut self, scalar: Scalar<'a>) {
3642
self.scalars.push(scalar);
3743
}
44+
45+
/// Kind of a yolo version of unused types check. But hey, it works. If somebody has lots of time
46+
/// in their hands, would be great to write this with cynic ;)
47+
pub fn remove_unused_types(&mut self) {
48+
let mut used_types = HashSet::new();
49+
50+
// First pass: collect type references from regular types
51+
for r#type in &self.types {
52+
for field in &r#type.fields {
53+
let type_name = field.r#type.replace("[", "").replace("]", "").replace("!", "");
54+
used_types.insert(type_name);
55+
56+
// Process any arguments
57+
for argument in &field.arguments {
58+
track_argument_inputs(&mut used_types, &argument.value);
59+
}
60+
}
61+
}
62+
63+
// Keep resolving dependencies until we reach a fixed point
64+
let mut size_before = 0;
65+
while size_before != used_types.len() {
66+
size_before = used_types.len();
67+
68+
// Process input types that are already marked as used
69+
for input in &self.input_types {
70+
if used_types.contains(input.name.as_ref()) {
71+
for field in &input.fields {
72+
let type_name = field.r#type.replace("[", "").replace("]", "").replace("!", "");
73+
used_types.insert(type_name);
74+
75+
// Process any arguments
76+
for argument in &field.arguments {
77+
track_argument_inputs(&mut used_types, &argument.value);
78+
}
79+
}
80+
}
81+
}
82+
}
83+
84+
// Filter scalars to only keep those that are used
85+
let mut scalars = Vec::new();
86+
for scalar in self.scalars.drain(..) {
87+
if used_types.contains(scalar.name) {
88+
scalars.push(scalar);
89+
}
90+
}
91+
92+
self.scalars = scalars;
93+
94+
// Filter input types to only keep those that are used
95+
let mut input_types = Vec::new();
96+
for input in self.input_types.drain(..) {
97+
if used_types.contains(input.name.as_ref()) {
98+
input_types.push(input);
99+
}
100+
}
101+
self.input_types = input_types;
102+
103+
self.scalars.sort_by_key(|scalar| scalar.name);
104+
self.enums.sort_by_key(|r#enum| r#enum.name);
105+
self.input_types.sort_by(|a, b| a.name.cmp(&b.name));
106+
107+
self.types.sort_by(|a, b| match (a.name.as_ref(), b.name.as_ref()) {
108+
("Query", "Mutation") => Ordering::Less,
109+
("Mutation", "Query") => Ordering::Greater,
110+
("Query", _) => Ordering::Greater,
111+
("Mutation", _) => Ordering::Greater,
112+
_ => a.name.cmp(&b.name),
113+
});
114+
}
115+
}
116+
117+
fn track_argument_inputs<'a>(used_inputs: &mut HashSet<String>, value: &'a ArgumentValue<'a>) {
118+
match value {
119+
ArgumentValue::Constant(constant) => {
120+
let type_name = constant.replace("[", "").replace("]", "").replace("!", "");
121+
used_inputs.insert(type_name);
122+
}
123+
ArgumentValue::Array(values) => values
124+
.iter()
125+
.for_each(|value| track_argument_inputs(used_inputs, value)),
126+
ArgumentValue::MultiLineArray { values, .. } => values
127+
.iter()
128+
.for_each(|value| track_argument_inputs(used_inputs, value)),
129+
_ => todo!(),
130+
}
38131
}
39132

40133
impl fmt::Display for Schema<'_> {

crates/postgres-introspection/src/render/ast/type.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,10 @@ use std::{
66
use super::{directive::Directive, field::Field};
77

88
pub struct Type<'a> {
9-
name: Cow<'a, str>,
10-
directives: Vec<Directive<'a>>,
11-
fields: Vec<Field<'a>>,
12-
description: Option<Cow<'a, str>>,
9+
pub(super) name: Cow<'a, str>,
10+
pub(super) directives: Vec<Directive<'a>>,
11+
pub(super) fields: Vec<Field<'a>>,
12+
pub(super) description: Option<Cow<'a, str>>,
1313
}
1414

1515
impl<'a> Type<'a> {

extensions/postgres/extension.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[extension]
22
name = "postgres"
3-
version = "0.4.0"
3+
version = "0.4.1"
44
description = """
55
Integrate your Postgres database directly into Grafbase Gateway. This extension exposes your database schema and with the help of the introspection tool, automatically generates a fully-functional GraphQL subgraph, eliminating the need to build and maintain a separate service.
66
"""

0 commit comments

Comments
 (0)